【问题标题】:c# Abstract Generic Class inheriting from Abstract Generic Class时间:2019-04-01 标签:c#Abstract Generic Class继承自Abstract Generic Class
【发布时间】:2014-10-10 10:29:04
【问题描述】:

我正在尝试创建一个继承自另一个抽象泛型类的抽象泛型类。

这是我目前所拥有的

public abstract class BaseClass {
    public long Id { get; private set; }

    public BaseClass(long id) {
        this.Id = id;
    }
}

public abstract class BaseClass<T> : BaseClass where T : BaseClass {
    protected BaseClass(long id)
        : base(id) {

    }

    public static T Get(long id) {
        T item;
        return TryGet(id, out item) ? item : default(T);
    }

    public static bool TryGet(long id, out T item) {
        item = null; // This is where I call the cache but for this example I've removed so it will compile
        if (item != null) { return true; }
        else {
            // Call TryGetFallback method
            return false;
        }
    }

    protected abstract T TryGetFallback(long id);
}


public abstract class DerivedClass : BaseClass<DerivedClass> {
    public String Name { get; private set; }

    public DerivedClass(long id, String name)
        : base(id) {
        this.Name = name;
    }
}

public class DerivedDerivedClass : DerivedClass {

    protected override DerivedDerivedClass TryGetFallback(long id) {
        // Handle the try get fallback
    }
}

DerivedDerivedClass 上的 TryGetFallback 方法会导致编译器错误。

【问题讨论】:

  • DerivedDerivedClass 继承自 DerivedClass,它继承自 DerivedClass,而 DerivedClass 继承自 BaseClass。您的链中没有 BaseClass,因此,您的方法不在链中。
  • BaseClass&lt;T&gt; 没有在任何地方使用!
  • 另外你确定你想让BaseClass&lt;T&gt; 的类型约束为BaseClass&lt;T&gt;,看起来有点……递归!
  • 嗨,DavidG,是的,我意识到了这一点,但我不知道如何将 BaseClass 放入链中。有任何想法吗?谢谢
  • 递归,BaseClass&lt;T&gt; 表示T 必须是BaseClass&lt;T&gt;,这意味着TBaseClass&lt;T&gt;....而且它一直是海龟!

标签: c# generics inheritance


【解决方案1】:

首先,您需要修复您的 BaseClass&lt;T&gt; 实现,使其不具有递归类型约束。

public abstract class BaseClass<T> : BaseClass where T : new() {
    //snip
}

然后你可以在你的派生类中使用它,例如我将使它使用int作为泛型类型参数:

public abstract class DerivedClass : BaseClass<int> {
    //snip
}

现在如果你编译它会警告你'DerivedDerivedClass' does not implement inherited abstract member 'BaseClass&lt;int&gt;.TryGetFallback(long)'

【讨论】:

  • 感谢 DavidG,我收到编译器错误:“DerivedClass”必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型中的参数“T”或方法 'BaseClass' 我在 DerivedClass 中有一个空的构造函数
  • 听起来你的类层次结构有点乱。
  • 你有没有让DerivedClass继承自BaseClass&lt;DerivedClass&gt;?如果是这样,请不要这样做。
  • 如果我不让 DerivedClass 从 BaseClass 继承,那么 DerivedDerivedClass 不会实现基类方法 TryGetFallback
  • 基本上我想要做的是在我的基类上有一个 TryGet 方法(我没有包含在我的代码 sn-p 中),它试图从缓存中获取对象,如果它是不在缓存中,它调用了我想在 DerivedDerived 类上处理的 TryGetFallback 方法
【解决方案2】:

感谢@DavidG 的提示,它帮助我用以下代码解决了问题

public abstract class BaseClass {
    public long Id { get; private set; }

    public BaseClass(long id) {
        this.Id = id;
    }
}

public abstract class BaseClass<T> : BaseClass where T : BaseClass<T>, new() {
    protected BaseClass(long id) : base(id) { }

    public static T Get(long id) {
        T item;
        return TryGet(id, out item) ? item : default(T);
    }

    public static bool TryGet(long id, out T item) {
        item = null; // Try to get item from cache here
        if (item != null) { return true; }
        else {
            T obj = new T();
            item = obj.TryGetFallback(id);
            return item != null;
        }
    }

    protected abstract T TryGetFallback(long id);
}

public abstract class DerivedClass<T> : BaseClass<T> where T : DerivedClass<T>, new() {
    public String Name { get; private set; }

    public DerivedClass() : base(0) {  }

    public DerivedClass(long id, String name)
        : base(id) {
        this.Name = name;
    }

    protected abstract override T TryGetFallback(long id);
}

public class DerivedDerivedClass : DerivedClass<DerivedDerivedClass> {

    public DerivedDerivedClass() {

    }

    protected override DerivedDerivedClass TryGetFallback(long id) {
        throw new NotImplementedException();
    }
}

【讨论】:

  • 创建一次性对象T obj = new T(); 的模式只是为了让您调用实例方法,这是黑客攻击的明显迹象。 TryGetFallback 方法不属于T,它属于一个相关但独立的类,通常称为“工厂”(link)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-21
  • 2020-05-07
  • 2016-10-23
  • 2011-01-31
  • 2013-04-11
  • 2015-07-04
  • 1970-01-01
相关资源
最近更新 更多