如何在Type上使用switch-case?
可能重复:
“开启型”有没有比这更好的选择?
我需要迭代我的类的所有属性,并检查我的类型int是否需要做什么,如果它的字符串..然后做一些事情。 我需要使用开关盒。 这里我以下面的方式使用开关,但它要求一些常量。 看下面的代码:
public static bool ValidateProperties(object o) { if(o !=null) { var sourceType = o.GetType(); var properties = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Static); foreach (var property in properties) { var type = property.GetType(); switch (type) { *case typeof(int):* getting error here // d } } } }
另外我想知道,我应该使用什么检查,typeof(int)或typeof(Int32)?
您不能使用开关块来测试Type
值。 编译代码应该会给出一个错误,例如:
switch表达式或case标签必须是bool,char,string,integral,enum或相应的可空类型
您需要使用if
– else
语句。
另外: typeof(int)
和typeof(Int32)
是等价的。 int
是关键字, Int32
是类型名称。
UPDATE
如果您希望大多数类型都是内在类型,则可以通过使用带有Type.GetTypeCode(...)
的开关块来提高性能。
例如:
switch (Type.GetTypeCode(type)) { case TypeCode.Int32: // It's an int break; case TypeCode.String: // It's a string break; // Other type code cases here... default: // Fallback to using if-else statements... if (type == typeof(MyCoolType)) { // ... } else if (type == typeof(MyOtherType)) { // ... } // etc... }
一个好的,可扩展的方法是根据你想要对那个类型的值做什么来制作一个适当类型的类型和委托的字典。
例如:
var typeProcessorMap = new Dictionary { { typeof(int), new Action(i => { /* do something with i */ }) }, { typeof(string), new Action(s => { /* do something with s */ }) }, };
然后:
void ValidateProperties(object o) { var t = o.GetType(); typeProcessorMap[t].DynamicInvoke(o); // invoke appropriate delegate }
此解决方案是可扩展的,即使在运行时也是可配置的,只要您保持typeProcessorMap
的委托值的键和类型正确匹配也是类型安全的。
看到它在行动 。
这个“答案”是对Jon的回答的详细说明。 (标记CW)
对于记录, DynamicInvoke
有点慢。 为了说明这一点,请考虑以下程序:
void Main() { Func myFunc = i => i.ToString(); myFunc.DynamicInvoke(1); // Invoke once so initial run costs are not considered myFunc(1); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < 1000000; i++) myFunc.DynamicInvoke(1); stopwatch.Stop(); var elapsed = stopwatch.Elapsed; stopwatch.Restart(); for (int i = 0; i < 1000000; i++) myFunc(1); stopwatch.Stop(); var elapsed2 = stopwatch.Elapsed; Console.WriteLine("DynamicInvoke: " + elapsed); Console.WriteLine("Direct Invocation: " + elapsed2); }
打印出来:
DynamicInvoke:00:00:03.1959900
直接调用:00:00:00.0735220
这意味着DynamicInvoke
(在这个简单的情况下)比直接调用慢42倍。
通常,最简单的解决方案是打开类型名称:
switch (type.Name) { case "Int32": ... }