2015-11-28 3 views
0

В настоящее время у меня есть класс, который инкапсулирует список типизированных объектов и реализует некоторые интерфейсы, такие как IEnumerable. Мне нужен второй класс с дополнительными, немного разными свойствами. Поэтому я буду создавать базовый класс A и получить новый класс B и новый класс C от A.Избегайте копирования и вставки почти общего кода в подклассы

Однако у меня есть код (например, как код для .Find с использованием делегатов), который почти такой же, как в B и C. Единственное отличие состоит в том, что код в B поиска в личном списке типизированных объектов (скажем, лицо) и код в C поиск приватного списка различных объектов (скажем, животные):

private static bool Find(Person xx) 
    { 
     if (xx.Id == someID) 
     { 
      return true; 
     } 
    else 
     { 
      return false; 
     } 
    } 

Как я хочу, чтобы избежать копирование/вставка, мой вопрос: что такое хорошая стратегия, чтобы избежать чего-то подобного?

Единственный способ, которым я представлял, состоял в том, чтобы объявить список общих объектов в A и указать методы в A на это. В B и C у меня тогда не было бы никакого кода, но я теряю все преимущества типизированного списка.

+0

Сделайте свой класс Обобщенный –

ответ

0

1) я хотел бы видеть, если я мог бы использовать дженерики при кодировании класса А

public class cA<T> 
{ 
    private IEnumerable<T> _myPrivateData 

    public bool Find(args) 
    { 
     // Do stuff with _myPrivateData 
    } 
} 

public class cB : cA<TheTypeIWant> 
{ 
    // more stuff here if needed 
} 

2) Вы можете использовать свойство переопределения функции + использование модификатора protected доступа сделать следующее:

public class cA 
{ 
    protected IEnumerable<Object> MyData { get; set; } 

    public bool Find(args) 
    { 
     // Do stuff with MyData 
    } 
} 

public class cB : cA 
{ 
    protected new IEnumerable<MyOtherDataType> MyData { get; set; } 
} 

Конечно, MyOtherDataType должен наследовать от базового типа, используемого для этого подхода. Однако я бы не рекомендовал этот подход. Вариант 1 намного лучше и чище.

Вот несколько ссылок, которые могут оказаться полезными:

+0

Если ваши объекты могут иметь идентификаторы, пример использования Папа Д'Амбры с использованием шаблона репозитория может быть интересным и очень хорошим решением. – LostBalloon

+0

Я искал дженерики, и это был самый простой ответ. Однако я также попытаюсь войти в шаблон репозитория. – Richard

0

Я был бы соблазн иметь интерфейс, как ICanBeFoundById

public interface ICanBeFoundById 
{ 
    int Id {get;} 
} 

затем Человек и животное может и наследовать имущество, что и вы можете сделать что-то вроде

public static class FindExtensions 
{ 
    public static bool Find(this IEnumerable<ICanBeFoundById> xs, int someID) 
    { 
    return xs.Any(x=>x.Id == someID) 
    } 
} 

Внимание: я не имею даже проверил, если это скомпилируется :)

Конечно, вы могли бы найти

public abstract class BaseRepository<ICanBeFoundById> 
{ 
    private IEnumerable<ICanBeFoundById> _xs; 

    public static bool Find(int someID) 
    { 
    return xs.Any(x=>x.Id == someID) 
    } 
} 

если вы не хотите иметь статическое расширение.

+1

Он должен компилироваться и работать с ни один вопрос не предусмотрено добавить «с помощью System.Linq "до кода – Machinarius

+0

я бы изменил' private IEnumerable _xs; 'как защищенный элемент, чтобы он мог его обновить и заставить тип в своих подклассах позволить ему сохранить преимущества типизированного списка [согласно № 2 в моем ответе] (я не думаю, что это обязательно должно быть свойство, хотя я никогда не пробовал на регулярном поле) – LostBalloon

+1

Да, мой очень примерный код .. все зависит от того, как вещи используются.Сила привычки печатать с защитой - я, как правило, скрываю вещи, пока они не станут более открытыми. –

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