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();
            }
        }
    }
}

有什么方法或解决方案可以满足我的需求吗?

谢谢!安娜

4

4 回答 4

3

您可以在基类型 ( )中创建Clone或在派生类型中创建,但在覆盖时不能更改返回类型,所以它必须是(没有更具体的)。您可以重新声明方法( ...),但这会变得混乱,并且您不能在同一类型中使用相同名称/签名的方法。abstractvirtualElementoverrideElementnewoverridenew

但是,如果您对返回类型感到高兴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 */; }
}
于 2010-02-20T10:18:58.663 回答
2

由于您从字典中获取的 .Value 类型是 Element,因此您需要确保 Element 定义了它应该具有的所有操作,例如您的 Clone 方法。

我会:

  1. 使克隆虚拟,并将其添加到元素(或使元素抽象,克隆抽象而不是虚拟)
  2. 在 Child1 和 Child2 中覆盖克隆

这样,代码kvp.Value.Clone()将根据字典返回的对象调用正确的 Clone 方法。

于 2010-02-20T10:14:09.707 回答
0

不要仅仅为了能够将不同的对象添加到一个字典中而创建类层次结构。

如果这些类没有足够好的层次关系,最好使用类似ICloneable.NET 框架中已经提供的接口。

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

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

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

于 2010-02-20T11:03:25.463 回答
0

尽管我同意 Wim 的观点,但实现ICloneable可能是更好的解决方案,而不是尝试强制执行不存在的类层次结构,请注意这ICloneable被认为是“糟糕的 API”,因为它没有指定是使用浅拷贝还是深拷贝语义(例如参见http://pro-thoughts.blogspot.com/2009/02/write-deep-clone-forget-about.html或在谷歌搜索“ICloneable C# bad API”

于 2010-02-20T11:50:14.263 回答