[英]Why does Assert.IsInstanceOfType(0.GetType(), typeof(int)) fail?
[英]Why typeof(int).ToString() is not constant?
我正在尝试这样做:
const string intType = typeof(int).ToString();
switch (typeof(MyT).ToString())
{
case intType:
{
return "int";
break;
}
...
}
但编译说:
错误CS0133:分配给'intType'的表达式必须是常量
据我所知, typeof
运算符在编译时工作。 那么,怎么了?
据我所知,typeof运算符在编译时工作。
你不知道 ,因为知识必须是真实的 。 你在哪里知道typeof
是在编译时执行的? 它产生一个非常数对象。 然后无法保证ToString
每次运行时都不会生成不同的字符串,因此也不能将其视为常量。
那么,怎么了?
你是从错误的信念中推理出来的。
C#规范清楚地描述了表达式作为编译时常量必须满足的条件。 这些条件包括不包含任何表达typeof
操作或方法调用。
但这里有更大的问题。 我假设MyT
是泛型类型参数,这意味着您正在尝试打开泛型类型参数的值。 这几乎总是错误的做法。
你真的想做什么? 你真的想解决什么问题? 因为到目前为止你所展示的这段代码表明你正在走一条非生产性的道路来解决真正的问题。
将MyT
类型与已知类型进行比较的唯一方法是检查其Type对象是否相等。 这可以按如下方式完成:
if (typeof(MyT) == typeof(int)) return "int";
if (typeof(MyT) == typeof(decimal)) return "decimal";
// etc...
您不能在switch
使用此方法,因为(此时) switch
要求检查的项目是简单类型:
switch (typeof(T)) // Compile error: "switch expression or case label must be a bool,
// char, string, integral, enum, or corresponding nullable type"
{
case typeof(int): return "int";
case typeof(decimal): return "decimal";
// ...
}
此外,正如其他人已经说过的那样,以这种方式检查类型几乎总是意味着可以通过应用不同的面向对象原则来改进您的方法。
例如,对MyMethod<MyT>(MyT item)
进行MyT
类型检查,考虑制作MyMethod(int item)
, MyMethod(decimal item)
等。
我认为,很明显,他想要实现的目标:
他想在switch-case
检查类型是否相等,而不是通过if-elseif
。 说实话,为什么不呢? 但他怎么能实现这个目标呢?
第一种选择:等待C#7.0 。 是的,这样的狗屎在未来是可能的!
第二个选项:使用字符串。 但是case
字符串需要保持不变。 那么这个美妙的nameof
怎么nameof
?
我刚试过这个“美女”并且它有效,所以这可能解决了你的问题:
switch (typeof(Int32).Name)
{
case nameof(Int32):
Console.WriteLine("It's an Int32!");
break;
case nameof(Double):
Console.WriteLine("It's a Double");
break;
}
如果您只是想获取描述对象类型的字符串,则只需要调用.GetType()。
例如,以下是一个小函数,它将返回对象类型的字符串名称。
static string GetTypeString(object obj)
{
return obj.GetType().FullName;
}
这将返回到对象的完整路径。 在int的情况下,它将返回System.Int32。 如果您只想要Int32部分,请改用GetType()。Name。
此外,你不需要休息; 如果你有回报,在交换机中;
如果您需要为某些类型运行特定代码,或者您想要返回的特定字符串,则可以对上面返回的值使用字符串。 例如:
static string GetSimpleType(object obj)
{
var stringRepresentation = GetTypeString(obj);
switch (stringRepresentation)
{
case "System.Int64":
case "System.Int32":
return "int";
default:
return stringRepresentation;
}
}
对于没有案例的所有内容,default都是switch语句中的catch。 把它想象成别的。
在上面的示例中,我们为int,Int32和Int64返回相同的值。 如果案例标签为空,则案例标签可以覆盖其他案例标签。
您可以通过运行简单的脚本找到编写开关所需的所有值,并对字符串值进行硬编码,因为它们对于相同的类型始终是相同的。 如果字符串不同,则类型不同。
最后,如果您要比较类型,if和if是否更好:
static string GetSimpleType(object obj)
{
if (obj.GetType() == typeof(int))
{
return "int";
}
return obj.GetType().ToString();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.