【发布时间】:2013-11-24 19:30:33
【问题描述】:
我知道目前的 C# 编译器不允许像这样打开类型
switch (typeof(MyObj))
case Type1:
case Type2:
case Type3:
有一些解决方案可以使用类型和动作字典或静态类 (link),但我只是好奇,为什么这是一种不好的做法或尚未在编译器中实现?
提前谢谢你。
【问题讨论】:
标签: c# .net compiler-optimization
我知道目前的 C# 编译器不允许像这样打开类型
switch (typeof(MyObj))
case Type1:
case Type2:
case Type3:
有一些解决方案可以使用类型和动作字典或静态类 (link),但我只是好奇,为什么这是一种不好的做法或尚未在编译器中实现?
提前谢谢你。
【问题讨论】:
标签: c# .net compiler-optimization
如果您在谈论原始类型,您可以切换 TypeCode。
var typeCode = Type.GetTypeCode(type);
switch (typeCode)
{
case TypeCode.Empty:
break;
case TypeCode.Object:
break;
case TypeCode.DBNull:
break;
case TypeCode.Boolean:
break;
case TypeCode.Char:
break;
case TypeCode.SByte:
break;
case TypeCode.Byte:
break;
case TypeCode.Int16:
break;
case TypeCode.UInt16:
break;
case TypeCode.Int32:
break;
case TypeCode.UInt32:
break;
case TypeCode.Int64:
break;
case TypeCode.UInt64:
break;
case TypeCode.Single:
break;
case TypeCode.Double:
break;
case TypeCode.Decimal:
break;
case TypeCode.DateTime:
break;
case TypeCode.String:
break;
}
顺便说一句,您可能需要阅读How many Microsoft employees does it take to change a lightbulb?的问题答案@
【讨论】:
我会向您推荐以下已接受的答案:switch statement in C# and "a constant value is expected"。编译器需要在编译时知道不会有任何重复,因此它只接受常量。顺便说一句,你可以用
达到同样的效果switch (typeof(MyObj).FullName
并使用每种类型的名称作为案例条件,例如:
case "MyNamespace.Type1":
/*stuff*/
break;
case "MyNamespace.Type2":
/*other stuff*/
break;
default:
/*default stuff*/
【讨论】:
您什么时候会使用开启类型?我能想到的大多数情况都可以通过继承更好地解决,即,而不是这样做:
switch (typeof(MyObj)) {
case Type1: doSomethingForType1; break;
case Type2: doSomethingForType2; break;
case Type3: doSomethingForType3; break;
您会以更加面向对象的方式进行设置:
Interface ISpecialType {
void doSomething();
}
Type1 : ISpecialType {
doSomething() {}
}
Type2 : ISpecialType {
doSomething() {}
}
Type3 : ISpecialType {
doSomething() {}
}
那么,不管怎样,你只需调用MyObj.doSomething(); 开始时打字会多一点,但更健壮。
另外,如果打开对您来说真的很重要,您可以随时使用 typeof(MyObj).toString() 并打开它。这不是推荐的做法,因为您随后会硬编码允许更改为您的开关的字符串,但您可以这样做。
【讨论】: