为什么我不能使用System.ValueType作为泛型约束?

时间:2009-12-06 07:15:44

标签: c# generics

  • 为什么我不能使用约束 where T : System.ValueType
  • 为什么Microsoft会阻止此类型 从约束?

示例:

为什么我不能做以下事情?

// Defined in a .Net class
public void bar<T>(T a) where T : ValueType {...}

// Defined in my class
public void foo<T>(T a) where T : ValueType 
{ bar<T>(a); }

使用struct over ValueType有什么区别?

// Defined in my class
public void foo<T>(T a) where T : struct 
{ bar<T>(a); }

4 个答案:

答案 0 :(得分:65)

使用

之间有两点不同
where T : struct

where T : ValueType
  • 后者允许T本身为ValueType,这是一种参考类型。
  • 后者也允许T成为可以为空的值类型

这些差异中的第一个几乎不是你想要的。第二个偶尔会有用; Nullable<T>有点奇怪,因为它既不满足where T : struct也不满足where T : class约束。

更有用的是约束

where T : struct, System.Enum

这是C#禁止的,因为我无法理解。有关详情,请参阅my blog postUnconstrained Melody project

答案 1 :(得分:12)

ValueType不是值类型的基类,它只是盒子化时值的容器。由于它是一个容器类,而不是您想要使用的实际类型的任何层次结构,因此它不能用作通用约束。

答案 2 :(得分:6)

使用struct作为通用约束在功能上等同于“ValueType”约束。在.NET中,a struct is a value type

答案 3 :(得分:0)

我认为下面的示例涵盖了ValueType所期望的许多用例。 T?的参数类型允许为空值,并且类型约束将其限制为实现IFormattable的结构,这对于我能想到的常见值类型是正确的。

public void foo<T>(T? a) where T : struct, IFormattable

请注意,这允许使用小数,日期时间,时间跨度等类型。

https://docs.microsoft.com/en-us/dotnet/api/system.iformattable?view=netcore-3.1