【问题标题】:How to declare a const field of a generic value type provided as generic argument如何声明作为泛型参数提供的泛型值类型的 const 字段
【发布时间】:2013-07-23 17:54:19
【问题描述】:

我正在尝试定义一个泛型类,它接受一个值类型(实际上它将是一个枚举)作为参数,并使用它的默认类型初始化一个 const 字段。

我想要类似的东西:

public abstract class GenericClass<ValueType> 
    where ValueType: struct, IConvertible
{
  public const ValueType val = default(ValueType);
}

不幸的是编译器抱怨(我使用的是 Mono,但我认为在 .NET 上也是如此)。错误如下:

错误 CS1959:类型参数 `ValueType' 不能声明为 const

我的错误是什么?

【问题讨论】:

    标签: c# generics enums value-type


    【解决方案1】:

    常量类型不允许有类型参数。

    因为不能将struct 设为const(来自C# 规范10.4 常量

    常量声明中指定的类型必须是sbytebyteshortushortintuintlongulong、@9876543324@、@987645 @、doubledecimalboolstring、枚举类型或引用类型。

    对此限制的一种解决方法是将其声明为static readonly

    public static readonly ValueType val = default(ValueType);
    

    【讨论】:

    • 还有没有强制 ValueType 成为枚举而不使用结构限制?
    • or a reference-type 部分有点混乱
    • @Heisenbug,没有。反正不是在编译时
    • @NikitaBrizhak “或引用类型的部分有点令人困惑”。为什么?这是有道理的……只有一个可能的值:null。 :D
    • @CédricBignon,我猜 :)
    【解决方案2】:

    根据its definition in MSDN:常量表达式是可以在编译时完全求值的表达式。

    根据this SO answer,引用this interview

    Anders Hejlsberg:[...] 在 CLR [公共语言运行时] 中,当您 编译 List 或任何其他泛型类型,它会编译为 IL [中间语言] 和元数据就像任何普通类型一样。伊利诺伊州 元数据包含知道存在类型的附加信息 参数,当然,但原则上,泛型类型只编译 任何其他类型的编译方式。在运行时,当你 应用程序第一次引用 List,系统看起来 如果有人已经要求列表。如果不是,它会输入 JIT List 的 IL 和元数据以及类型参数 int。 JITer, 在JITing IL的过程中,还替换了类型参数。

    因此,由于在编译时没有定义类型,所以直到运行时才能获取默认值。

    【讨论】:

    • 实际上应该可以在编译时评估它。
    • @Heisenbug,没有。自定义结构可以有一个自定义的默认构造函数,它可以做许多不同的事情,不能被评估
    • @NikitaBrizhak:错了。结构不能有自定义的默认构造函数。
    • @SLaks,真的。我的意思是自定义(参数化)构造函数,不确定“默认”这个词来自哪里:)
    猜你喜欢
    • 2018-12-14
    • 2020-11-11
    • 1970-01-01
    • 2017-12-06
    • 1970-01-01
    • 2015-11-07
    • 2021-12-08
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多