c# Abstract Generic Class inheriting from Abstract

2020-04-21 02:04发布

问题:

I'm trying to create an abstract generic class which inherits from another abstract generic class.

Here's what I have so far

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
    }
}

The TryGetFallback method on the DerivedDerivedClass causes a compiler error.

回答1:

First you need to fix your BaseClass<T> implementation to not have a recursive type constraint.

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

Then you can use it in your derived class, for example I will make it use int for the generic type parameter:

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

And now if you compile it will warn you that 'DerivedDerivedClass' does not implement inherited abstract member 'BaseClass<int>.TryGetFallback(long)'



回答2:

Thanks for the tips @DavidG it's helped me to solve the problem with the following code

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();
    }
}