为什么Enum.TryParse需要约束,其中T:struct

时间:2017-12-15 09:15:48

标签: c# struct enums

我正在尝试了解将string转换为Enum找到here的扩展方法。

public static T ToEnum<T>(this string value, T defaultValue)
{
     if (string.IsNullOrEmpty(value))
     {
        return defaultValue;
     }

     T result;
     return Enum.TryParse<T>(value, true, out result) ? result : defaultValue;
}

编译错误:

  

类型'T'必须是不可为空的值类型才能将其用作   泛型类型或方法中的参数'TEnum'   'Enum.TryParse(string,bool,out TEnum)'

注释之一是添加where T : struct以使扩展方法起作用。

带约束的方法:

public static T ToEnum<T>(this string value, T defaultValue) where T : struct
{
    if (string.IsNullOrEmpty(value))
    {
          return defaultValue;
    }

    T result;
    return Enum.TryParse<T>(value, true, out result) ? result : defaultValue;
}

我在Enum.TryParse上阅读了文档,但我在文档中并不了解为什么where T : struct被添加为类型T的约束?

为什么上面的扩展不会在没有约束的情况下工作struct为什么不是其他值类型?如何关联structEnum类型?或者它只是一种语法?

更新

他们中的大多数人说可以使用任何值类型,我尝试使用where T : int但是我得到编译时错误:

  

'int'不是有效的约束。用作约束的类型必须是   接口,非密封类或类型参数。

2 个答案:

答案 0 :(得分:1)

约束 struct不仅包含您通过struct MyStruct声明的类型,还包含许多内置类型,例如int,{{1 }或byte。实际上,约束将char限制为任何值类型,请参阅C#-specification 9.4.5 Satisfying constraints

  

如果约束是值类型约束(struct),则类型A应满足以下

之一      
      
  • A是结构类型或枚举类型,但不是可为空的值类型。 [注意:System.ValueType和System.Enum是这样做的引用类型   不满足这个约束。结束说明]
  •   
  • A是具有值类型约束(第15.2.5节)
  • 的类型参数   

当然,如果存在更严格的约束条件,那就太好了。

编辑时:在这种情况下,您的编译器消息非常清楚。使用类型作为约束时,只能使用接口或非密封类。限制泛型类型参数以完全匹配单个类(或结构)会使泛型无用,不是吗?将您的通用限制为T会有效地将您的方法签名转换为以下内容:

int

因为只有一个结构符合约束条件。

答案 1 :(得分:0)

这样做是为了在编译时启用部分错误检查:

  • 引用类型在编译时被拒绝,
  • enum的值类型在运行时被拒绝。

如果你能写where T : Enum会更好,但C#编译器禁止这样做:

  

约束不能是特殊类`System.Enum'

有关此错误see this Q&A的详细信息。特别是,请参阅this answer,了解问题的简要解决方法。