2014-06-19 1 views
0

Вот прообраз того, что я хотел бы сделать, за исключением того, что я понимаю, что она не может работать так, как я написал это:Возможно ли (частично) реализовать абстрактный метод и по-прежнему требуют, чтобы производные классы также реализовали его?

using System.Collections.ObjectModel; 

namespace Merlinia.CommonClasses 
{ 
    public abstract class JustTesting<TItem> : KeyedCollection<string, TItem> 
    { 
     protected override string GetKeyForItem(TItem anItem) 
     { 
     return GetKeyForItem(anItem).ToUpperInvariant(); 
     } 

     protected new abstract string GetKeyForItem(TItem anItem); 
    } 
} 

Теперь я понимаю, что, изменив название из абстрактный метод я требую в производных классах, что делает работу:

using System.Collections.ObjectModel; 

namespace Merlinia.CommonClasses 
{ 
    public abstract class JustTesting<TItem> : KeyedCollection<string, TItem> 
    { 
     protected override string GetKeyForItem(TItem anItem) 
     { 
     return NewGetKeyForItem(anItem).ToUpperInvariant(); 
     } 

     protected abstract string NewGetKeyForItem(TItem anItem); 
    } 
} 

это просто, что я предпочел бы, что имя метода было то же самое, GetKeyForItem, во всех классах. Есть ли способ сделать эту работу?

+2

Нет, насколько я знаю, и это было бы очень запутанным, если вы могли бы - в конце концов, кто-то читает * только * верхние и нижние классы (а не абстрактные средние) были бы предположить, что они были переопределяя метод в классе * top *. –

+0

@JonSkeet: Хорошо, спасибо. (Поместите его как ответ, если вы хотите получить очки для него. :-) – RenniePet

+0

Это невозможно сделать, хотя можно использовать явные реализации интерфейса, внешний вызов (т.е. «частично» реализованный метод) будет доступен только через ссылку на интерфейс. Поэтому лучше всего предоставить второе имя второму методу, он фактически представлен в самой структуре в 'System.Reflection.MemberInfo'. –

ответ

2

Для этого вы можете вставить дополнительный класс и внутреннюю вспомогательную функцию в иерархии.

using System.Collections.ObjectModel; 

namespace Merlinia.CommonClasses 
{ 
    public abstract class JustTestingBase<TItem> : KeyedCollection<string, TItem> 
    { 
     internal JustTestingBase() 
     { 
     // so that other assemblies cannot misuse this as their own base class 
     } 

     protected sealed override string GetKeyForItem(TItem anItem) 
     { 
     return GetKeyForItemHelper(anItem).ToUpperInvariant(); 
     } 

     internal abstract string GetKeyForItemHelper(TItem anItem); 
    } 

    public abstract class JustTesting<TItem> : JustTestingBase<TItem> 
    { 
     protected new abstract string GetKeyForItem(TItem anItem); 

     internal override string GetKeyForItemHelper(TItem anItem) 
     { 
     return GetKeyForItem(anItem); 
     } 
    } 
} 
+0

ОК, спасибо, это делает трюк. Но теперь, размышляя, я думаю, что я возьму совет Джона Скита и просто переименую метод, который требуется в моих производных классах. – RenniePet

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