C# 为什么可以';我是否使用System.ValueType作为泛型约束? 为什么我不能使用约束 其中T:System.ValueType 为什么Microsoft会阻止这种类型 从成为一个约束
示例: 为什么我不能做以下事情C# 为什么可以';我是否使用System.ValueType作为泛型约束? 为什么我不能使用约束 其中T:System.ValueType 为什么Microsoft会阻止这种类型 从成为一个约束,c#,generics,C#,Generics,示例: 为什么我不能做以下事情 // 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); } //在.Net类中定义 公共无效条(TA),其中T:ValueType{…} //在我的课堂上 public
// 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); }
//在.Net类中定义
公共无效条(TA),其中T:ValueType{…}
//在我的课堂上
public void foo(ta),其中T:ValueType
{bar(a);}
在ValueType上使用struct有什么区别
// Defined in my class
public void foo<T>(T a) where T : struct
{ bar<T>(a); }
//在我的类中定义
公共void foo(ta)其中T:struct
{bar(a);}
ValueType不是值类型的基类,它只是装箱时值的容器。由于它是一个容器类,并且不在您想要使用的实际类型的任何层次结构中,因此它不可用作泛型约束。使用struct
作为泛型约束在功能上等同于“ValueType”约束。在.NET中,.使用
where T : struct
及
- 后者将允许
成为T
本身,这是一种引用类型ValueType
- 后者还允许
为可空值类型T
Nullable
有点奇怪,因为它既不满足where T:struct
也不满足where T:class
约束
更有用的是约束
where T : struct, System.Enum
这是C#禁止的,我看不出有什么好的理由。有关这方面的更多信息,请参阅和。我认为下面的示例涵盖了ValueType所期望的许多用例。T的参数类型?允许空值,并且类型约束将其限制为实现IFormattable的结构,这对于我所能想到的常见值类型是正确的
public void foo<T>(T? a) where T : struct, IFormattable
public void foo(T?a),其中T:struct,IFormattable
请注意,这允许诸如decimal、datetime、timespan之类的类型
我不得不说,我一直在想,我们不能像
那样限制它们,其中t:struct,System.Enum
。有时它会非常有用!实际上,您可以在F#中执行where T:Enum
和where T:ValueType
(使用它的语法when'T:>Enum
),实际上,它按照Jon的预期工作。对于枚举类型约束,它可以与通用枚举(如enum
和System.enum
)一起使用,并正确地禁止同义值类型(如byte
或int
)。为了回答Jon关于“为什么”的问题,很难将其添加到C#中,请参见Roslyn的讨论:我到了一个地方,实际上我想说ValueType的所有具体实现,包括nullable。(实际约束是其中T:ValueType,New)不完全且不完全。在IL中,您可以清楚地看到任何具有扩展System.ValueType的值类型的声明,这使它有效地成为基类。我认为它的主要作用是作为区分类和值类型的标记,但我不确定。结论(“作为泛型约束不有用”)是正确的,但答案的其余部分不是。ValueType“为值类型提供基类。”(from)和“…它是所有值类型的基类…”(from)结构是ValueType
,是的,但不是每个值类型都是结构,例如,ValueType
本身不是结构,也不是可为空的值类型。我认为这个答案不正确,基于公认的答案。
public void foo<T>(T? a) where T : struct, IFormattable