將switch case轉為條件驅動
switch case是一種.net里面常用的條件分支語句,挺好用的;不過有些缺點:
1.在有包含大量條件和執行語句的時候代碼結構會很亂。
2.不太符合面對對象的設計原則。
3.對于查詢條件是否滿足一定范圍這樣的邏輯不太好用。
將其轉為條件驅動的實現,(本例使用Dictionary+Delegate的方式)
View Code
class SwitchTest
{
/// <summary>
/// 常規寫法
/// </summary>
/// <param name="type"></param>
public static void Test(EnumType type)
{
switch (type)
{
case EnumType.A:
break;
case EnumType.B:
break;
case EnumType.C:
break;
case EnumType.D:
break;
case EnumType.E:
break;
case EnumType.F:
break;
case EnumType.G:
break;
case EnumType.H:
break;
case EnumType.I:
break;
case EnumType.J:
break;
case EnumType.K:
break;
default:
break;
}
}
#region 下面所有的代碼是另一種實現方法. 關鍵是handlers的初始化
static Dictionary<EnumType, Action<object>> handlers = new Dictionary<EnumType, Action<object>>();
static SwitchTest()
{
var methods = typeof(SwitchTest).GetMethods();
var fields = Enum.GetNames(typeof(EnumType)).ToList();
foreach (var item in methods)
{
if (item.Name.StartsWith("Handle"))
{
var commandTypeName = item.Name.Substring(6, item.Name.Length - 6);
if (fields.Contains(commandTypeName))
{
EnumType type = (EnumType)Enum.Parse(typeof(EnumType), commandTypeName);
handlers[type] = (Action<object>)Delegate.CreateDelegate(typeof(Action<object>), item);
}
}
}
//也可以通過下面的代碼,初始化Dictionary
//handlers[EnumType.A] = new Action<object>(HandleA);
//handlers[EnumType.B] = new Action<object>(HandleB);
//handlers[EnumType.C] = new Action<object>(HandleC);
// ....
//當然 也可以通過其他邏輯初始化Dictionary
}
/// <summary>
/// 使用Dictionary 加上 Delegate的寫法
/// </summary>
/// <param name="enumType"></param>
internal static void Test2(EnumType enumType)
{
//如果要設計為可以處理一定范圍的邏輯, 可以在這里添加一個方法處理輸入值,例如1-20的值都認為是處理邏輯A
if (handlers.ContainsKey(enumType))
{
handlers[enumType](null);
}
else
{
//默認處理邏輯
}
}
public static void HandleA(object obj)
{
}
public static void HandleB(object obj)
{
}
public static void HandleC(object obj)
{
}
public static void HandleD(object obj)
{
}
public static void HandleE(object obj)
{
}
public static void HandleF(object obj)
{
}
public static void HandleG(object obj)
{
}
public static void HandleH(object obj)
{
}
public static void HandleI(object obj)
{
}
public static void HandleJ(object obj)
{
}
#endregion
}
/// <summary>
/// 用于演示的枚舉類型
/// </summary>
public enum EnumType
{
A = 1,
B = 2,
C = 3,
D = 4,
E = 5,
F = 6,
G = 7,
H = 8,
I = 9,
J = 10,
K = 11,
}
1.常用的委托有Action<T> 和 Func<T>
2.也可以自己定義委托以支持任意方法
3.可以傳遞Delegate的方式實現更為復雜的多重邏輯
4.毫無疑問,在簡單的情況下不是很使適用條件驅動這樣相對復雜的方案
關于性能問題:
//準備數據
Random random = new Random();
int length = 1000000;
EnumType[] testData = new EnumType[length];
for (int i = 0; i < length; i++)
{
testData[i] = (EnumType)Enum.Parse(typeof(EnumType), random.Next(1, 11).ToString());
}
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < testData.Length; i++)
{
SwitchTest.Test(testData[i]);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);//13 執行100萬次
sw.Restart();
for (int i = 0; i < testData.Length; i++)
{
SwitchTest.Test2(testData[i]);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);//62 執行100萬次
執行10萬次分別消耗9毫秒 和7毫秒,
執行100萬次分別消耗13毫秒 和62毫秒,
(可能有點誤差,不過這樣小的消耗主要是為了表明其實兩種寫法的性能權重都不高)
好久之前的東西了。。。最近正好又遇到,就記錄在blog中,順便看看有沒有什么可以優化的地方

浙公網安備 33010602011771號