C#generics约束

是否可以枚举通用约束中“可用”的类型?

T MyMethod() where T : int, double, string 

为什么我要这样做是因为我有一个小的评估引擎,并且想编写这样的代码:

 bool expression.Evaluate(); 

要么

 int expression.Evaluate(); 

但我想禁止

 MyCustomClass expression.Evalaute(); 

无法将generics参数限制为特定类型。

作为一种变通方法,您可以为每种类型提供一种方法,并将方法调用转发到一个通用实现:

 public class Expression { public bool EvaluateToBool() { return Evaluate(); } public int EvaluateToInt32() { return Evaluate(); } private T Evaluate() { return default(T); } } 

另一方面,您是否考虑过在Expression类型中对表达式求值的类型进行编码? 例如

 public abstract class Expression { public abstract T Evaluate(); } public sealed class AddExpression : Expression { public AddExpression(Expression left, Expression right) { this.Left = left; this.Right = right; } public Expression Left { get; private set; } public Expression Right { get; private set; } public override int Evaluate() { return this.Left.Evaluate() + this.Right.Evaluate(); } } 

如果generics类型参数的可能性很小,那么该方法不是真正通用的 。 generics的要点是允许类型和方法的参数化,以便您可以根据需要创建无限多种不同的类型和方法。 如果您只有三种可能的类型,那么请编写三种方法。 也就是说,创建重载,不要使用generics。

不,你不能。

您可以添加以下通用约束:

 T MyMethod() where T : struct {} 

然后:

 bool expression.MyMethod(); //OK int expression.MyMethod(); //OK string expression.MyMethod(); //fails! string is a reference type struct MyStruct {} MyStruct MyMethod(); //OK! MyStruct is a value type class MyCustomClass {} MyCustomClass MyMethod(); //FAILS! MyCustomClass is a reference type 

但是你不能同时为int和string添加编译时约束。