2012-04-20 3 views
4

У меня есть два класса (это C#), которые очень похожи, за исключением того, что каждый из них содержит свой собственный вложенный класс и перечисление.Сокращение дублирования кода в двух классах с разными вложенными классами

Я хотел бы реорганизовать их как наследуемый из одного абстрактного класса, но я столкнулся с проблемой, потому что все методы тесно связаны с вложенными типами классов.

Мой первый план состоял в том, чтобы вытащить класс ItemDetails, но он связан с ItemType, который является перечислением, которое относится к каждому классу элемента представления. Кроме того, я не могу просто использовать System.Enum как тип, так как мне нужно иметь возможность сериализовать детали в XML-файл.

Как я могу уменьшить дублирование внутри этих классов?

public class FirstViewItem 
{ 
    [Serializable] 
    public class ItemDetails 
    { 
     public ItemType Type; 
     public int Width; 
     public string Text; 
     public int DisplayOrder; 
    } 

    public enum ItemType 
    { 
     None = 0, 
     A, 
     B, 
     C 
    } 

    public FirstViewItem() 
    { 
     // ... 
    } 

    public List<ItemDetails>() 
    { 
     // code here ... 
    } 
} 

public class SecondViewItem 
{ 
    [Serializable] 
    public class ItemDetails 
    { 
     public ItemType Type; 
     public int Width; 
     public string Text; 
     public int DisplayOrder; 
    } 

    public enum ItemType 
    { 
     None = 0, 
     X, 
     Y, 
     X 
    } 

    public SecondViewItem() 
    { 
     // ... 
    } 

    public List<ItemDetails>() 
    { 
     // code here ... 
    } 
} 
+1

Это, вероятно, лучше всего подходит для [Просмотр Кода] (http://codereview.stackexchange.com/) ... –

+0

я даже не знал, что существует ... красиво! – chills42

ответ

5

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

public class ViewItem<T> 
{ 
    [Serializable] 
    public class ItemDetails 
    { 
     public T Type; // the generic type is inserted here 
     public int Width; 
     public string Text; 
     public int DisplayOrder; 
    } 

    // common code that uses ItemDetails 
} 

Тогда некоторые типы элементов:

public enum FirstItemType 
{ 
    None = 0, 
    A, 
    B, 
    C 
} 

public enum SecondItemType 
{ 
    None = 0, 
    X, 
    Y, 
    Z 
} 

Тогда использование:

var firstViewItem = new ViewItem<FirstItemType>(); 
+0

Я сохранил отдельные классы, но изменил общий класс, как вы показали, также является абстрактным и унаследованным от него. – chills42

2

Яньменский проспект r является хорошим.

Я начал писать это, чтобы закончить. Вот пример использования генерик с базовым классом и некоторые наследующие классы:

public class BaseClass<T> 
{ 
    public T NestedClass{get;set;} 
} 

public class MainOne : BaseClass<MainOneType> 
{ 
} 

public class MainTwo : BaseClass<MainTwoType> 
{ 
} 

public class MainOneType 
{ 
} 

public class MainTwoType 
{ 
} 
+0

+1, это хорошие примеры, которые, вероятно, очень актуальны для исходного вопроса. – yamen

+0

Я закончил с комбинацией этого и того, что имел @yamen. – chills42

0

Я закончил с использованием идеи из 2-х разных ответов, так что я отвечу с комбинированным результатом.

public class BaseViewItem<T> where T : struct 
{ 
    [Serializable] 
    public class ItemDetails 
    { 
     public T Type; 
     public int Width; 
     public string Text; 
     public int DisplayOrder; 
    } 

    public FirstViewItem() 
    { 
     // ... 
    } 

    public List<ItemDetails>() 
    { 
     // code here ... 
    } 
} 

public class FirstViewItem : BaseViewItem<FirstItemType> 
{ 
    // class-specific code... 
} 

public class SecondViewItem : BaseViewItem<SecondItemType> 
{ 
    // class-specific code... 
} 

public enum FirstItemType 
{ 
    None = 0, A, B, C 
} 

public enum SecondItemType 
{ 
    None = 0, X, Y, Z 
} 
Смежные вопросы