Is it possible to enumerate which types that is "available" in a generic constraint?
T MyMethod<t>() where T : int, double, string
Why I want to do this is that I have a small evaluator engine and would like to write code like this:
bool expression.Evaluate<bool>();
or
int expression.Evaluate<int>();
but i want to prohibit
MyCustomClass expression.Evalaute<MyCusto开发者_运维知识库mClass>();
If you have a small number of possibilities for the generic type argument then the method is not truly generic. The point of generics is to allow parameterization of types and methods so that you can create infinitely many different such types and methods on demand. If you only have three possible types then write three methods. That is, create overloads, don't use generics.
It is not possible to restrict a generic argument to specific types.
As a workaround, you could provide a method for each type and forward the method calls to a common implementation:
public class Expression {
public bool EvaluateToBool() {
return Evaluate<bool>();
}
public int EvaluateToInt32() {
return Evaluate<int>();
}
private T Evaluate<T>() {
return default(T);
}
}
On the other hand, have you thought about encoding the type the expression evaluates to in the Expression type? E.g.
public abstract class Expression<T> {
public abstract T Evaluate();
}
public sealed class AddExpression : Expression<int> {
public AddExpression(Expression<int> left, Expression<int> right) {
this.Left = left;
this.Right = right;
}
public Expression<int> Left { get; private set; }
public Expression<int> Right { get; private set; }
public override int Evaluate() {
return this.Left.Evaluate() + this.Right.Evaluate();
}
}
No, you can't.
You can add the following generic constraint:
T MyMethod<T>() where T : struct {}
And then:
bool expression.MyMethod<bool>(); //OK
int expression.MyMethod<int>(); //OK
string expression.MyMethod<string>(); //fails! string is a reference type
struct MyStruct {}
MyStruct MyMethod<MyStruct>(); //OK! MyStruct is a value type
class MyCustomClass {}
MyCustomClass MyMethod<MyCustomClass>(); //FAILS! MyCustomClass is a reference type
But you can't add compile time constraints for int and string simultaneously.
精彩评论