2014-10-10 3 views
0

Я пытаюсь создать абстрактный общий класс, который наследуется от другого абстрактного обобщенного класса.C# Абстрактный универсальный класс, наследующий от абстрактного обобщенного класса

Вот что я до сих пор

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

Метод TryGetFallback на DerivedDerivedClass вызывает ошибку компилятора.

+2

DerivedDerivedClass наследует от DerivedClass , который наследует от DerivedClass, который наследуется от BaseClass. В вашей цепочке нет BaseClass , поэтому ваш метод не в цепочке. – kha

+0

'BaseClass ' нигде не используется! – DavidG

+1

Также вы уверены, что ограничение типа для BaseClass '' должно быть 'BaseClass ', кажется немного ... рекурсивным! – DavidG

ответ

1

Прежде всего, вам нужно исправить свою реализацию BaseClass<T>, чтобы не было ограничения рекурсивного типа.

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<int>.TryGetFallback(long)'

+0

Спасибо DavidG, я получаю ошибку компилятора: «DerivedClass» должен быть не абстрактным типом с открытым конструктором без параметров, чтобы использовать его как параметр «T» в родовом типе или методе «BaseClass ». У меня есть пустой конструктор в DerivedClass – NeilT

+0

Похоже, что вы немного повсюду со своей иерархией классов. – DavidG

+0

Вы случайно сделали 'DerivedClass' наследованием от' BaseClass '? Если да, не делайте этого. – DavidG

0

Спасибо за советы @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(); 
    } 
} 
+0

Шаблон, в котором вы создаете отбрасываемый объект 'T obj = new T();', который есть только для того, чтобы вы могли вызвать метод экземпляра, это четкая индикация взлома.Метод 'TryGetFallback' не принадлежит' T', он принадлежит к связанному, но отдельному классу, который часто называют «фабрикой» ([ссылка] (http://en.wikipedia.org/wiki/Factory_method_pattern)) , – dasblinkenlight

Смежные вопросы