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

zfe*_*ran 48 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); }
Run Code Online (Sandbox Code Playgroud)

使用struct而不是ValueType有什么区别?

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

Jon*_*eet 66

使用之间有两点不同

where T : struct
Run Code Online (Sandbox Code Playgroud)

where T : ValueType
Run Code Online (Sandbox Code Playgroud)
  • 后者将允许TValueType本身,这是一个引用类型.
  • 后者也允许T成为可以为空的值类型

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

更有用的是约束

where T : struct, System.Enum
Run Code Online (Sandbox Code Playgroud)

这是C#所禁止的,没有任何理由我可以告诉.有关详细信息,请参阅我的博客文章Unconstrained Melody项目.

  • 我不得不说,我总是想知道我们不能限制它们像`where T:struct,System.Enum`.它有时*非常有用! (6认同)

Rex*_*x M 13

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

  • 不完全也不完全.在IL中,您可以清楚地看到具有`extends System.ValueType`的任何值类型的声明,这使它实际上成为基类.我认为它的主要作用是区分类和值类型的标记,但我不确定. (3认同)

bob*_*mcr 6

使用struct作为通用约束在功能上等同于"ValueType"约束.在.NET中,struct是值类型.

  • struct是一个“ ValueType”,是的,但是并不是每个值类型都是一个结构,例如,“ ValueType”本身不是结构,也不是可为空的值类型。 (3认同)