【发布时间】:2013-02-28 21:51:05
【问题描述】:
我有两个对象序列“A”和“B”。比较序列应产生第三个元素序列“C”,指示是否:
- 对象已从“A”或 中“删除”
- 从“B”“插入”。
所有剩余的元素都被认为是“匹配的”。
我想做的事:
声明Inserted<T>、Deleted<T> 和Matched<T> 泛型类,它们从T 基类继承其所有属性。泛型类必须能够从它继承的对象实例化自己。
代码:
public interface IInstantiable<T>
{
void CopyFrom(T o);
}
[Serializable]
public class Inserted<T> : T
where T : IInstantiable<T>
{
public Inserted() { }
public Inserted(T t)
{
this.CopyFrom(t);
}
}
错误:
'MyNamespace.Inserted<T>' does not contain a definition for 'CopyFrom' and no
extension method 'CopyFrom' accepting a first argument of type 'MyNamespace.Inserted<T>'
could be found (are you missing a using directive or an assembly reference?)
进一步讨论:
我定义了自己的IInstantiable 接口来强制CopyFrom 方法的存在。我不能使用标准的ICloneable 接口,因为它只定义了一个将对象复制到新实例的方法,而我需要对象在构造函数中复制其成员。
如果泛型定义了自己的CopyFrom 方法实现,错误就会消失;但是,这并没有达到将CopyFrom 方法专门用于处理基类的特定需求的预期目标。只有基类可以知道应该复制哪些属性。 (或者我错过了什么?)
注意:最终对象应该具有与其基类相同的公共成员,因为该对象应该能够序列化。
这在 .NET 中可行吗?
答案:
我试图做的事情是不可能的,仅仅是因为泛型类不能是模板基类的扩展。 Visual Studio 抱怨“不能从 'T' 派生,因为它是一个类型参数。” (我还没有注意到这个错误,因为我还没有在泛型类中实现CopyFrom 方法。)
如果我要将接口更改为一个类并在该类中提供一个存根实现,我可以按照下面的建议从它继承;但是,这会在我的继承层次结构中引入一个新的基类。
public class IInstantiable<T>
{
public virtual void CopyFrom(T o) { }
}
[Serializable]
public class Inserted<T> : IInstantiable<T>
where T : IInstantiable<T>
{
public Inserted() { }
public Inserted(T t)
{
base.CopyFrom(t);
}
}
不幸的是,我不能以模板化形式使用这个新的基类,因为我必须在继承层次结构的根部引入它。仅当我删除模板并使其尽可能通用时才有效。
public class IInstantiable
{
public virtual void CopyFrom(Object o) { }
}
但是,这仍然不能使我的Inserted<T> 泛型看起来像它初始化的对象,并且由于我不能从与类型参数相同的类型继承,所以它不适合我的初始目的。
从基于类型系统的“花哨的泛型”转向更多(咳咳)泛型注释结构可能被证明是最好的解决方案;但是,我选择的序列化方法 (XmlSerialization) 的默认行为不具有使此配置成为可行解决方案的自动支持。泛型将不起作用;改用硬编码的类定义。
【问题讨论】:
-
首先
Inserted<T> : T是不允许的。 -
看起来你只是想要:
public class Inserted<T> : IInstantiable<T>。这不适合你吗? -
好吧,我确实注意到您没有从
IInstantiable<T>继承,您只是基于它创建了一个模板化类型。你试过public class Inserted<T> : IInstantiable<T> : where T IInstantiable<T>吗? (实际上,由于您没有模板化 where 不会编译,所以不要这样做)
标签: c# generics inheritance interface