2010-02-20 60 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,因此您需要确保Element定义了它应该具有的所有操作,例如Clone方法。

我想:

  1. 让克隆虚拟,并将其添加到元素(或使元素抽象的,克隆抽象的,而不是虚拟的),在这两个Child1和CHILD2
  • 覆盖克隆

    这样,代码kvp.Value.Clone()将调用正确的克隆方法,具体取决于从字典返回的对象。

  • 3

    你可以做的派生类型Clone要么abstractvirtual在基型(Element)和override,但压倒一切,当你不能改变返回类型,所以它必须是Element(无更具体)。你可以重新声明的方法(new ...),但这会变得凌乱,而且你不能在同一类型中使用相同名称/签名的方法overridenew

    但如果你是幸福的返回类型是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

    不要只为了能够给不同的对象添加到一个字典起见,创建一个类层次结构虽然。

    如果这些类没有足够体面的层次关系,那么最好使用像.NET框架中已有的接口ICloneable

    然后,只需实例化你的字典,如:

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

    它更灵活。为了能够执行Clone()的通用性创建层次结构不是正确的解决方案IMO。

    0

    虽然我与维姆同意,实施ICloneable可能是更好的解决方案,而不是试图执行一个不存在的类层次,请注意,ICloneable被认为是一个“坏API”,因为它不指定它使用浅层或深层复制的语义(例如参见http://pro-thoughts.blogspot.com/2009/02/write-deep-clone-forget-about.html或在谷歌搜索“ICloneable C#bad API”