【问题标题】:Abstract Class -- How to specify return of generic list抽象类——如何指定泛型列表的返回
【发布时间】:2016-06-08 17:24:52
【问题描述】:

我对此有一些困难。我有一个抽象类,我想为其继承者添加一个公共抽象方法来实现。挑战在于该方法应该返回实现完全不同的抽象类 (NotifyingDatabaseObject) 的类的通用列表。

我想做如下的事情,但它不会编译:

public abstract IList<T> GetList(int? id) where T : NotifyingDatabaseObject;

当然,如果我将“T”替换为“NotifyingDatabaseObject”,它将要求继承类返回该抽象类而不是具体类。

关于我如何做到这一点的任何方向?

谢谢!

【问题讨论】:

    标签: c# generics abstract-class


    【解决方案1】:

    如果返回类型与抽象类或具体类无关,则可以在方法上使用类型参数,例如:

    public abstract IList<T> GetList<T>(int? id) where T : NotifyingDatabaseObject;
    

    具体的类应该是这样的:

    class MyConcreteClass : MyAbstractClass
    {
        public override IList<NotifyingDatabaseObjectChildClass> GetList<NotifyingDatabaseObjectChild>(int? id)
        {
            return new List<NotifyingDatabaseObjectChildClass>();
        }
    }
    

    【讨论】:

    • 编译测试! ;) 唯一的缺点是在调用方法时必须再次传递类型:var mylist = concrete.GetList&lt;NotifyingDatabaseObjectChild&gt;(10); 那是因为它无法从用法中推断出类型。
    • 谢谢 - 这似乎工作得很好!我将不得不跑回去再次阅读泛型手册。
    • 好的,这将编译,但这不是目的,因为NotifyingDatabaseObjectChild 是一个类型参数,而不是具体类型。在这种情况下,返回一个空列表是唯一可能的实现,因为实现者没有关于T 的其他信息。在这种情况下,您不妨将实现移至基类。
    • 他从未说过返回类型应该是具体的:the method should return a generic list of classes that implement a totally different abstract class,但是,如果是这样,我们可以将约束添加到抽象类:where T : NotifyingDatabaseObject, new();
    • 这个被覆盖的版本没有什么是在基类中无法做到的。这种方法只有在 OP 希望每个子类执行不同的通用构造时才有效,这是极不可能的。
    【解决方案2】:

    我假设您希望基类的每个子类都返回NotifyingDatabaseObject特定 子类型。在这种情况下,您应该向基类添加一个类型参数,并让每个子类型指定它们返回的 NotifyingDatabaseObject 的哪个子类型:

    public abstract class MyAbstractClass<T>
        where T : NotifyingDatabaseObject
    {
        public abstract IList<T> GetList(int? id) ;
    }
    
    public class MyConcreteClass : MyAbstractClass<NotifyingDatabaseObjectChildClass>
    {
        public override IList<NotifyingDatabaseObjectChildClass> GetList(int? id)
        {
            return new List<NotifyingDatabaseObjectChildClass>();
        }
    }
    

    请注意,现有答案并没有这样做 - 它要求每个子类型支持返回 NotifyingDatabaseObjectany 子类型列表,而不仅仅是一个特定的。在这种情况下,唯一可能的实现是返回一个空列表(或 null,或抛出异常,或无限循环),因为实现类没有构造 T 类型值的通用方法。

    【讨论】:

    • 你是对的——它确实需要返回一个特定的子类型。让我研究一下,我会根据需要进行修改。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多