以下範例圖片皆為實際應用且運行中的程式碼 ## 巢狀if ![範例1-1](https://hackmd.io/_uploads/rkB9Ppdih.png) ![範例1-2](https://hackmd.io/_uploads/Hyz3wT_o2.png) ![範例1-3](https://hackmd.io/_uploads/S1gRP6Oi2.png) ![範例1-4](https://hackmd.io/_uploads/Byvkdpdon.png) ![範例1-5](https://hackmd.io/_uploads/SyU-OaOs2.png) ## 非0即1的分支使用if,或是iif 三元運算子 ```csharp if(isSuccess) { } else { } var message = isSuccess == true ? "1" : "0"; ``` ## 超過2個分支,請使用switch case 或 switch pattern matching;數量在3-5個之間或視複雜程度自行權衡 [switch pattern-matching in msdn](https://learn.microsoft.com/zh-tw/dotnet/csharp/fundamentals/functional/pattern-matching) ```csharp switch(operationType) { case "add": break; case "delete": break; case "update": break; default: break; } public State PerformOperation(string command) => command switch { "SystemTest" => RunDiagnostics(), "Start" => StartSystem(), "Stop" => StopSystem(), "Reset" => ResetToReady(), _ => throw new ArgumentException("Invalid string value for command", nameof(command)), }; ``` ## 已經超過5個或7個以上的分支,請使用Dictionary<string ,Func`<Action>>`的方式,利用字典+迴圈來擇一執行或條件判斷執行 ```csharp class Program { public static int Add(int x, int y) => x + y; public static int Subtract(int x, int y) => x - y; public static int Multiply(int x, int y) => x * y; public static int Divide(int x, int y) => x / y; static void Main(string[] args) { var operations = new Dictionary<string, Func<int, int, int>> { { "add", Add }, { "subtract", Subtract }, { "multiply", Multiply }, { "divide", Divide } }; Console.WriteLine("Enter an operation (add, subtract, multiply, divide): "); string operation = Console.ReadLine().ToLower(); Console.WriteLine("Enter the first operand: "); int operand1 = Int32.Parse(Console.ReadLine()); Console.WriteLine("Enter the second operand: "); int operand2 = Int32.Parse(Console.ReadLine()); if (operations.ContainsKey(operation)) { int result = operations[operation](operand1, operand2); Console.WriteLine($"Result: {result}"); } else { Console.WriteLine("Operation not recognized."); } } } ``` ## 其他 ![範例2](https://hackmd.io/_uploads/Skbvdaujh.jpg) 是否有其他方式能避免使用大量if,觀察邏輯與規律撰寫演算法解決,以上圖為例在了解檔名與位置之間的關聯後,使用迴圈讀取陣列產生檔名,以下為簡單的實作 ```csharp public static class GeneratExtensions { public static string MapToImage(this IEnumerable<int> list) { int count = 0; var result = ""; foreach(var item in list) { count++; if(item>0) result += count.ToString(); } result = string.IsNullOrEmpty(result) ? "def" : result; return $"b{result}_map"; } } public class MultipleIfTests { [Theory] [Trait("map","image")] [InlineData(new[]{ 0, 0, 0, 0},"bdef_map")] [InlineData(new[]{ 1, 0, 0, 0},"b1_map")] [InlineData(new[]{ 1, 1, 0, 0},"b12_map")] [InlineData(new[]{ 1, 1, 1, 0},"b123_map")] [InlineData(new[]{ 1, 1, 1, 1},"b1234_map")] [InlineData(new[]{ 0, 1, 0, 0},"b2_map")] [InlineData(new[]{ 0, 1, 1, 0},"b23_map")] [InlineData(new[]{ 0, 1, 1, 1},"b234_map")] [InlineData(new[]{ 0, 0, 1, 0},"b3_map")] [InlineData(new[]{ 0, 0, 1, 1},"b34_map")] [InlineData(new[]{ 0, 0, 0, 1},"b4_map")] public void test_map_to_image(int[] map ,string imageName) { // Given List<int> list = new List<int>(); list.AddRange(map); // When var value = list.MapToImage(); // Then Assert.Equal(imageName,value); } } ``` 使用linq ```csharp public class MultipleIfTests { [Theory] [Trait("map","image")] [InlineData(new[]{ 0, 0, 0, 0},"bdef_map")] [InlineData(new[]{ 1, 0, 0, 0},"b1_map")] [InlineData(new[]{ 1, 1, 0, 0},"b12_map")] [InlineData(new[]{ 1, 1, 1, 0},"b123_map")] [InlineData(new[]{ 1, 1, 1, 1},"b1234_map")] [InlineData(new[]{ 0, 1, 0, 0},"b2_map")] [InlineData(new[]{ 0, 1, 1, 0},"b23_map")] [InlineData(new[]{ 0, 1, 1, 1},"b234_map")] [InlineData(new[]{ 0, 0, 1, 0},"b3_map")] [InlineData(new[]{ 0, 0, 1, 1},"b34_map")] [InlineData(new[]{ 0, 0, 0, 1},"b4_map")] public void test_map_to_image(int[] map ,string imageName) { // Given List<int> list = new List<int>(); list.AddRange(map); // When var result = list .Select((value,index) => value > 0 ? (index + 1).ToString() : "") .Aggregate("",(current , next) => current + next); var value = $"b{ string.IsNullOrEmpty(result) ? "def" : result}_map"; // Then Assert.Equal(imageName,value); } } ``` 使用function方式串接 ```csharp public static class LinqExtensions { public static Func<int, int, string> HasValuePosition => (value, index) => value > 0 ? (index + 1).ToString() : ""; public static string MapToImage(this IEnumerable<int> list) => list .Select((value, index) => HasValuePosition(value, index)) .Aggregate((current, next) => current + next).ToImageName(); public static string ToImageName(this string value) => $"b{(string.IsNullOrEmpty(value) ? "def" : value)}_map"; } public class MultipleIfTests { [Theory] [Trait("map", "has_value_position")] [InlineData(0, 0, "")] [InlineData(1, 0, "1")] [InlineData(1, 1, "2")] public void test_has_value_position(int val,int index,string expected) { // Given // When var result = LinqExtensions.HasValuePosition(val, index); // Then Assert.Equal(expected, result); } [Theory] [Trait("map", "image_name")] [InlineData("", "bdef_map")] [InlineData("1", "b1_map")] public void test_to_image_name(string value, string expected) { // Given // When var result = value.ToImageName(); // Then Assert.Equal(expected, result); } [Theory] [Trait("map", "image")] [InlineData(new[] { 0, 0, 0, 0 }, "bdef_map")] [InlineData(new[] { 1, 0, 0, 0 },"b1_map")] [InlineData(new[] { 1, 1, 0, 0 }, "b12_map")] [InlineData(new[] { 1, 1 ,1, 0 }, "b123_map")] [InlineData(new[] { 1, 1, 1, 1 }, "b1234_map")] [InlineData(new[] { 0 ,1, 0, 0 }, "b2_map")] [InlineData(new[] { 0, 1, 1, 0 }, "b23_map")] [InlineData(new[] { 0, 1, 1, 1 }, "b234_map")] [InlineData(new[] { 0, 0, 1, 0 }, "b3_map")] [InlineData(new[] { 0, 0, 1, 1 }, "b34_map")] [InlineData(new[] { 0, 0, 0, 1 }, "b4_map")] public void test_map_to_image(int[] map, string imageName) { // Given List<int> list = new List<int>(); list.AddRange(map); // When var value = list.MapToImage(); // Then Assert.Equal(imageName, value); } } ```