开发者

C# generic constraints [duplicate]

开发者 https://www.devze.com 2022-12-21 22:46 出处:网络
This question already has answers here: Is there a constraint that restricts my generic method to numeric types?
This question already has answers here: Is there a constraint that restricts my generic method to numeric types? (24 answers) Closed 8 years ago.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消