为什么Enum.TryParse需要约束,其中T:struct
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么Enum.TryParse需要约束,其中T:struct相关的知识,希望对你有一定的参考价值。
我试图了解一种扩展方法将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'必须是非可空值类型才能在泛型类型或方法'Enum.TryParse(string,bool,out TEnum)'中将其用作参数'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'不是有效的约束。用作约束的类型必须是接口,非密封类或类型参数。
约束struct
不仅包括您通过struct MyStruct
声明的类型,还包括许多内置类型,如int
,byte
或char
。实际上约束将T
限制为任何值类型,请参阅C#-specification 9.4.5 Satisfying constraints:
如果约束是值类型约束(struct),则类型A应满足以下之一
- A是结构类型或枚举类型,但不是可空值类型。 [注意:System.ValueType和System.Enum是不满足此约束的引用类型。结束说明]
- A是具有值类型约束的类型参数(第15.2.5节)
当然,如果存在更严格的约束,那将是很好的。
在编辑时:在这种情况下,您的编译器消息非常清楚。使用类型作为约束时,您只能使用接口或非密封类。限制泛型类型参数以恰好匹配一个单独的类(或结构)会使泛型非常无用,不是吗?将您的泛型限制为int
将有效地将您的方法签名转换为如下所示:
public static int ToEnum(this string value, int defaultValue)
因为只有一个结构匹配约束。
这样做是为了在编译时启用部分错误检查:
- 引用类型在编译时被拒绝,
- 不是
enum
s的值类型在运行时被拒绝。
如果你能编写where T : Enum
会更好,但C#编译器禁止这样做:
约束不能是特殊类`System.Enum'
有关此错误的更多信息,请访问see this Q&A。特别是,请参阅this answer以简要解决问题。
以上是关于为什么Enum.TryParse需要约束,其中T:struct的主要内容,如果未能解决你的问题,请参考以下文章
`<T extends E>` 形式的通用约束,其中`E` 是`enum`?
当其中一个是本地引用时,如何为类型约束中的引用编写生命周期?