简体   繁体   English

使用类型约束实现泛型类时出错

[英]Error implementing Generic Class with Type Constraints

I have a Generic Base Class that I want to allow one of two types ITest or IBoldface . 我有一个通用基类,我想允许使用两种类型之一ITestIBoldface

My Base Class looks like this: 我的基类如下所示:

public abstract class BaseTestingCollections<T> where T : ITest, IBoldface
{
...
}

One of the classes that inherit it looks like this: 继承它的类之一如下所示:

public class TestCollection : BaseTestingCollections<ITest>, ITestCollection
{
...
}

When I compile I get this error: 编译时出现此错误:

The type DomainLogic.ITest' cannot be used as type parameter 'T' in the generic type or method 'DomainLogic.BaseTestingCollections'. 在通用类型或方法“ DomainLogic.BaseTestingCollections”中,类型DomainLogic.ITest'不能用作类型参数“ T”。 There is no implicit reference conversion from 'DomainLogic.ITest' to 'DomainLogic.IBoldface'. 没有从“ DomainLogic.ITest”到“ DomainLogic.IBoldface”的隐式引用转换。

Such an either/or restriction can't be done (as I'm sure you've noticed, the comma is more like && than || ). 这样的一个或一个限制是不可能完成的(正如我确定您已经注意到的那样,逗号更像&&不是|| )。 You can either make two different abstract classes with different names (one BaseTestingCollectionsTest<T> where T : ITest , the other BaseTestingCollectionsBoldface<T> where T : IBoldface ), or remove the static restriction and put the check at runtime. 您可以使用不同的名称(一个BaseTestingCollectionsTest<T> where T : ITest ,另一个BaseTestingCollectionsBoldface<T> where T : IBoldface )来创建两个不同的抽象类,或者删除静态限制并将检查放在运行时。 Or make one of ITest or IBoldface extend the other, or extend a common interface, if they share members. 或者使ITestIBoldface扩展另一个,或者扩展一个公共接口(如果它们共享成员)。

Here's an example of checking at runtime: 这是在运行时检查的示例:

public abstract class BaseTestingCollections<T>
{
    public BaseTestingCollections()
    {
        if (!typeof(ITest).IsAssignableFrom(typeof(T)) && !typeof(IBoldface).IsAssignableFrom(typeof(T)))
            throw new Exception();
    }
}

Well you're not satistfying the constraint you've specified. 嗯,您没有满足您指定的约束。 T has to extend/implement both ITest and IBoldFace . T必须扩展/ 同时实现ITest IBoldFace

Your constraint doesn't mean that it has to extend/implement one of the types - it has to do both . 您的约束并不意味着它必须扩展/实现的类型之一 -它必须两者都做。 A type argument has to satisfy all the type constraints in order to be valid. 类型自变量必须满足所有类型约束才能生效。

See MSDN on generic constraints for more information. 有关一般信息,请参见MSDN

Per your own generic constraint, only those types which implement both ITest and IBoldface are suitable generic arguments for your BaseTestingCollection class. 根据您自己的通用约束,只有那些同时实现 ITestIBoldface类型BaseTestingCollection类的合适通用参数。

It's not either-or, how could it be? 不是-或者是,怎么可能? What happens when you call method Bar from the ITest interface on a T which only implements IBoldFace , which in turn defines no method Bar ? 当您从仅实现IBoldFaceT上的ITest接口调用方法Bar时会发生什么,而后者又没有定义方法Bar What is a compiler to do when faced with such a scenario? 面对这种情况,编译器该怎么办?

There is no reasonable action to take. 没有采取任何合理的措施。 Your constraints apply all at the same time to the generic argument. 您的约束将全部同时应用于通用参数。

You can't express an "either-or" constraint like this with C# generics. 您无法使用C#泛型来表达“非此即彼”的约束。 Use a common base interface of some sort: 使用某种通用的基本接口:

interface ITestOrBold {}
interface ITest : ITestOrBold {}
interface IBoldface : ITestOrBold {}

class BaseTestingCollections<T> where T : ITestOrBold {}

Obviously instead of ITestOrBold you should have some sensible abstraction. 显然,应该使用一些明智的抽象来代替ITestOrBold

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM