为什么';tc#是否允许将typeof作为默认参数?

为什么';tc#是否允许将typeof作为默认参数?,c#,typeof,default-parameters,C#,Typeof,Default Parameters,typeof(MyClass)不是编译时常量吗?来自MSDN-: 默认值必须是以下表达式类型之一: 恒定的表达式 形式为new ValType()的表达式,其中ValType是值类型,如枚举或结构 默认形式的表达式(ValType),其中ValType是值类型 typeof不一定返回编译时常量,因为它可能会根据上下文返回不同的结果。因为它不一定是常量表达式。您的示例在一个简单类上提供了一个typeof,但是如果该类是泛型的呢?显然,到目前为止,这并不是恒定不变的: class MyC

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

来自MSDN-:

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

  • 恒定的表达式

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

  • 默认形式的表达式(ValType),其中ValType是值类型



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

因为它不一定是常量表达式。您的示例在一个简单类上提供了一个typeof,但是如果该类是泛型的呢?显然,到目前为止,这并不是恒定不变的:

class MyClass
{
    public void MyMethod(Type targetType = typeof(MyClass))
    {
    }
}
class-MyClass
{
公共void MyMethod(类型targetType=typeof(MyClass))
{
}
} 

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

class MyClass<T>
{
  public void MyMethod(Type targetType = typeof(MyClass<T>))
  {
  }
} 
这与以下内容相同:

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);
typeof(MyClass)
不是编译时常量吗

该特定表达式是静态可解析的,但是
typeof()
是在执行时计算的(因为泛型),因此规则必须是
typeof()
调用不是编译时常量


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

这已经很古老了,但如果有人正在寻找解决办法:

Constant initialize must be compile-time constant

传递给
typeof
的类型必须在编译时解析。因此我不明白你的意思。如果你说的是真的,属性也应该不允许“类型常量”。leppie,你所说的“属性也应该不允许“类型常量”是什么意思?属性在哪里将值限制为常量?@Fujiy-传递给属性构造函数的参数需要是编译时常量。Oded,规则是:常量、表达式类型或数组创建+1回答问题并证明它不是编译时常量的好方法
RuntimeTypeHandle
是常量,但是,RuntimeTypeHandle是一个结构。不管怎样,这是什么变化?RuntimeTypeHandle只是方法callI的参数,我不认为泛型是唯一的原因。我认为这是因为它是有效的:
typeof(ClassInExternalAssembly)
。直到实际的外部程序集被加载,所以它不能被解析,因此它不是常数。如果你习惯于C++中的泛型类型,那么它可能是常数,其中每种可能的类型<代码> t>代码>生成类的新实例。这不是它在C和.NET中的工作方式,因此在C#
typeof(T)
中不能是编译时常量,但在基于模板的泛型语言中应该是。
    class MyClass
    {
        public void MyMethod(Type targetType = null)
        {
            if(targetType == null)
            {
                targetType = typeof(MyClass);
            }
        }
    }