将C#通用约束指定为ClassA或ClassB?

时间:2010-01-15 19:25:07

标签: c# generics

有没有办法指定泛型类型是一种类型另一种类型?

public class SoftDrink<T>
    where T : TypeOne or TypeTwo
{ }

6 个答案:

答案 0 :(得分:8)

不,因为那没有任何意义。如果您尝试访问“T”的成员函数,编译器如何告诉哪个基类尝试并解析成员?

您可以尝试为TypeOne和TypeTwo创建一个公共接口,并让约束指定该接口?你到底想要完成什么?

答案 1 :(得分:3)

你做不到。您可以做的最好的事情是使用两者的公共基类,或者将两者实现的公共接口作为单一类型约束。

答案 2 :(得分:2)

不,但是,您可以在公共基础或接口上约束该类。

在CLR本身中,约束(除了特殊的约束之外,比如新约束)的存储相当简单:基本上只是一个类型标识符列表。所以对于你已经指定的逻辑运算来说真的没有“空间”......不是没有对CLR规范的修订,也可能是一些非常聪明和丑陋的语言级技巧。

答案 3 :(得分:2)

您可以将TypeOne和TypeTwo的常用功能提取到基类或接口中,并使用该基类或接口作为约束。否则,编译器将如何知道它可以用T做什么?

public interface IBelch
{
    void Belch();
}

public class Coke : IBelch
{
    public void Belch()
    {
    }
}

public class GatorAde : IBelch
{
    public void Belch()
    {
    }
}

public class SoftDrink<T>
    where T : IBelch
{
    public void DrinkFast(T drink)
    {
        drink.Belch();
    }
}

答案 4 :(得分:2)

您可以随时对类型进行运行时检查:

class TypeOne
{
    int _integer = 0;
}

class TypeTwo
{
    int _integer = 3;
}

class TypeThree
{
}

class SoftDrink<T>
{
    public SoftDrink()
    {
        if (typeof(T) != typeof(TypeOne) && typeof(T) != typeof(TypeTwo))
        {
            throw (new Exception("Sorry, but T must be TypeOne or TypeTwo"));
        }
    }
}

//this works:
SoftDrink<TypeOne> t1 = new SoftDrink<TypeThree>();    

//throws an exception:
SoftDrink<TypeThree> t3 = new SoftDrink<TypeThree>();

答案 5 :(得分:0)

您可以让TypeOne和TypeTwo继承接口,然后执行以下操作。

 public class SoftDrink<T>
    where T: IMyType
    {}