2010-02-20 4 views
4

Я новичок в C# вещь .... (.net 3.5)Список с различными типами

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

namespace ConsoleApplication1 { 
    class Element{ 
    } 
    class Child1 : Element { 
     public Child1 Clone() { return clone; } 
    } 
    class Child2<T> : Element { 
     public Child2<T> Clone() { return clone; } 
    } 
    class Program { 
     static void Main(string[] args) { 
      Dictionary<string, Element> d = new Dictionary<string, Element>(); 
      d.Add("c1", new Child1()); 
      d.Add("c2s", new Child2<string>()); 
      d.Add("c2i", new Child2<int>()); 
      foreach (KeyValuePair<string, Element> kvp in d) { 
       Element e = kvp.Value.Clone(); 
      } 
     } 
    } 
} 

Есть ли способ или решение для моих потребностей?

Спасибо! Anna

ответ

2

Поскольку тип .Value вы получаете из своего словаря, это элемент, вам нужно убедиться, что Element определяет все операции, которые он должен иметь, например, ваш метод Clone.

Я:

  1. Сделать клон виртуальной, и добавить его в элемент (или сделать элемент абстрактный и Clone абстрактный вместо виртуального)
  2. Override Clone в обоих ребенка1 и ребенка2

Таким образом, код kvp.Value.Clone() вызовет правильный метод Clone в зависимости от объекта, возвращаемого из словаря.

3

Вы могли бы сделать Clone либо abstract или virtual на базовом типа (Element) и override его в производных типах, но вы не можете изменить тип возвращаемого при переопределении, поэтому она должна была бы быть Element (ничего более конкретно). You может методы redeclare (new ...), но это становится беспорядочным, и вы не можете использовать override и new метод с тем же именем и подписями того же типа.

Но если вы счастливы для типа возвращаемого быть Element ...

abstract class Element{ 
    public abstract Element Clone(); 
} 
class Child1 : Element { 
    public override Element Clone() { return /* your code */; } 
} 
class Child2<T> : Element { 
    public override Element Clone() { return /* your code */; } 
} 
0

Не создавать иерархию классов просто ради того, чтобы быть в состоянии добавить различные объекты в одном словаре хоть.

Если классы не имеют достаточно приличных иерархических отношений, вам будет лучше использовать интерфейс, такой как ICloneable, который уже доступен в .NET framework.

Тогда просто инстанцируйте свой словарь, как:

Dictionary<string, ICloneable> d = new Dictionary<string, ICloneable>(); 

Это более гибкая. Создание иерархии ради общности возможности выполнять Clone() не является правильным решением IMO.

0

Хотя я согласен с Wim, что реализация ICloneable является, вероятно, лучшим решением, а не пытаться применять несуществующий класс иерархию, следует помнить, что ICloneable считается «плохим API», поскольку это не указывает ли это использует неглубокую или глубокую семантику (см., например, http://pro-thoughts.blogspot.com/2009/02/write-deep-clone-forget-about.html или выполните поиск в Google «ICloneable C# bad API»

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