是否存在“where not derived from”的泛型类型约束?

时间:2012-06-25 18:14:35

标签: c# generics

我们可以在泛型类型参数上指定“派生自”约束,如下所示:

class Bar<T> where T : IFooGenerator

有没有办法指定 NOT 派生自?


我的用例:我有一堆可并行化的FooGenerator,每个都有相同的并行化代码,但我们不希望它们始终并行化。

public class FooGenerator : IFooGenerator
{
    public Foo GenerateFoo() { ... }
}

因此,我创建了一个用于并行生成Foo的通用容器类:

public class ParallelFooGenerator<T> : IFooGenerator where T : IFooGenerator
{
    public Foo GenerateFoo()
    {
        //Call T.GenerateFoo() a bunch in parallel
    }
}

由于我希望FooGeneratorParallelFooGenerator<FooGenerator>可以互换,因此我制作了ParallelFooGenerator : IFooGenerator。但是,我显然不希望ParallelFooGenerator<ParallelFooGenerator>合法。

所以,作为一个辅助问题,如果“不是从”派生的约束是不可能的话,是否有更好的方法来设计这个?

3 个答案:

答案 0 :(得分:10)

您可以使用以下内容:

public interface IFooGenerator
{
    Foo GenerateFoo();
}

interface ISerialFooGenerator : IFooGenerator { }

interface IParallelFooGenerator : IFooGenerator { }

public class FooGenerator : ISerialFooGenerator
{
    public Foo GenerateFoo()
    {
        //TODO
        return null;
    }
}

public class ParallelFooGenerator<T> : IParallelFooGenerator
    where T : ISerialFooGenerator, new()
{
    public Foo GenerateFoo()
    {
        //TODO
        return null;
    }
}

答案 1 :(得分:7)

ParallelFooGenerator<ParallelFooGenerator>已经不可能,因为ParallelFooGenerator是泛型类型而您没有指定泛型参数。

例如,ParallelFooGenerator<ParallelFooGenerator<SomeFooGenerator>>是可能的 - 并允许这样的类型真的那么糟糕?

答案 2 :(得分:4)

简单的答案是否定的。

答案很长(仍然没有):

Microsoft在其explanation of type constrains中表示良好:&#34;编译器必须保证它需要调用的运算符或方法将受到客户端代码可能指定的任何类型参数的支持。 #34;

约束的根本目的不是禁止使用某些类型,而是允许编译器知道支持哪些运算符或方法。但是,您可以在运行时check if a type implements/inherits a specific interface/base class并抛出异常。但是,通过这种方式,您将无法从intellisense中获得设计时错误。

我希望这会有所帮助。