我正在尝试了解将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
为什么不是其他值类型?如何关联struct
和Enum
类型?或者它只是一种语法?
更新
他们中的大多数人说可以使用任何值类型,我尝试使用where T : int
但是我得到编译时错误:
'int'不是有效的约束。用作约束的类型必须是 接口,非密封类或类型参数。
答案 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,了解问题的简要解决方法。