class MyClass
{
public void MyMethod(Type targetType = typeof(MyClass))
{
}
}
是不是typeof(MyClass)
编译时常量?为什么C#不允许typeof作为默认参数?
class MyClass
{
public void MyMethod(Type targetType = typeof(MyClass))
{
}
}
是不是typeof(MyClass)
编译时常量?为什么C#不允许typeof作为默认参数?
从MSDN - Named and Optional Parameters:
A default value must be one of the following types of expressions:
a constant expression;
an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct;
an expression of the form default(ValType), where ValType is a value type.
typeof
不一定返回编译时间常数,因为它可以根据上下文返回不同的结果。
因为它不一定是一个常量表达式。你的例子在一个简单的类上有一个typeof,但是如果这个类是通用的呢?显然这是不恒定迄今为止:
class MyClass<T>
{
public void MyMethod(Type targetType = typeof(MyClass<T>))
{
}
}
我不是IL专家,但似乎它来电L_0005的方法:
return typeof(int);
It's相同的:
.maxstack 1
.locals init (
[0] class [mscorlib]System.Type typeofvar)
L_0000: ldtoken int32
L_0005: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
L_000a: stloc.0
L_000b: ldloc.0
L_000c: ret
你可以看到,它不是一个代码不变写作类型:
const Type constType = typeof(int);
返回一个错误:
Constant initialize must be compile-time constant
Isn't
typeof(MyClass)
a compile-time constant?
即特定表达是静态解析的,是的,但typeof()
在执行时(因为泛型)被评估,所以规则必须是一个typeof()
调用不是编译时常量。
我不知道它是否在C#1.0中,当有来作出上述说法 ...
我不认为泛型是唯一的原因。我认为这是因为它的工作原理:'typeof(ClassInExternalAssembly)'。在实际的外部装配被加载之前它不能被解决,因此它不是恒定的。 – Aidiakapi
类型传递给'typeof'必须在编译时得到解决。因此我看不出你的意思。如果你说的是真的,属性也应该禁止'类型常量'。 – leppie
leppie,你的意思是“属性也应该禁止'类型常量'”?属性在什么地方将值限制为常量? –
@Fujiy - 传递给属性构造函数的参数需要是编译时间常量。 – Oded