为什么C#不允许typeof作为默认参数?

时间:2012-01-20 09:48:36

标签: c# typeof default-parameters

class MyClass
{
    public void MyMethod(Type targetType = typeof(MyClass))
    {
    }
}

typeof(MyClass)不是编译时常量吗?

5 个答案:

答案 0 :(得分:11)

我不是IL专家,但似乎它在L_0005上调用了一个方法:

return typeof(int);

同样的:

.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

答案 1 :(得分:5)

来自MSDN - Named and Optional Parameters

  

默认值必须是以下类型的表达式之一:

     
      
  • 一个常量表达式;

  •   
  • 新形式ValType()的表达式,其中ValType是值类型,例如枚举或结构;

  •   
  • 表单default(ValType),其中ValType是值类型。

  •   

typeof不一定返回编译时常量,因为它可能会根据上下文返回不同的结果。

答案 2 :(得分:4)

因为它不一定是常量表达式。你的例子在一个简单的类上有一个typeof但是如果这个类是通用的呢?显然这远远不是常数:

class MyClass<T>
{
  public void MyMethod(Type targetType = typeof(MyClass<T>))
  {
  }
} 

答案 3 :(得分:1)

  

typeof(MyClass)不是编译时常量吗?

特定的表达式是静态可解析的,是的,但是typeof()在执行时被评估(因为泛型),所以规则必须是typeof()调用不是编译时常量。

我确实想知道C#1.0中是否 ,当时没有这样的论据......

答案 4 :(得分:0)

这很旧,但是如果有人正在寻找解决方法:

    class MyClass
    {
        public void MyMethod(Type targetType = null)
        {
            if(targetType == null)
            {
                targetType = typeof(MyClass);
            }
        }
    }