C# generic constraints [duplicate]

被刻印的时光 ゝ 提交于 2019-12-30 05:55:11

问题


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<MyCustomClass>();

回答1:


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();
    }
}



回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/2391968/c-sharp-generic-constraints

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!