为什么我不能将XmlAttribute和XmlElement都设置为通用约束?

时间:2013-07-31 10:19:39

标签: c# .net generics

我试图将XmlAttributeXmlElement设置为通用类型的允许类型,但是当我同时设置它们时,我会得到一个编译时出错:

  

类类型约束' System.Xml.XmlElement'必须在任何之前   其他约束

代码示例:

interface TestClass<T, T2> : IEnumerable where T2: XmlAttribute, XmlElement
{
    ...        
} 

为什么它不允许我设置这样的约束?

4 个答案:

答案 0 :(得分:3)

您正在使用的约束 not 表示允许类型的列表。这意味着“为T2插入的任何内容都必须继承。”

这样编译器可以确保为T2插入的任何内容都提供了某个公共接口 - 属性和方法 - 即从指定类型继承的那些接口。如果您可以在那里列出多个替代方案,哪个接口将被视为理所当然?根据要插入的内容,T2可以包含XmlAttribute 提供的所有方法和属性XmlElement提供的所有方法和属性,但没有他们肯定是。

答案 1 :(得分:1)

当您列出以逗号分隔的多个约束时,您告诉C#T必须满足所有 *这些约束,而不是一个或另一个。你不能约束说T必须是两个类之一。通过约束类型参数,可以将允许的操作和方法调用的数量增加到约束类型支持的数量和您列出的所有接口作为类型约束。这就是首先使用基于类的类和基于接口的约束的目的 - 让您调用超出System.Object类支持的操​​作。

因此,您永远不会在约束列表中放置两个类(但是您可以根据需要放置一个类和多个接口)。即使这两个类是相关的,将最多的一个放在约束中也相当于将两个类放在一起。

答案 2 :(得分:0)

请注意,XmlAttributeXmlElement之间的逗号表示,而不是XmlAttributeXmlElement是类,由于C#没有多重继承,因此任何泛型参数都不可能满足约束。

答案 3 :(得分:0)

你不能这样做的原因是因为这两种类型有不同的成员。考虑在一个方法上使用它,身体内部会发生什么?如何在不知道传入哪种类型的情况下编写方法?自动完成如何对这种约束做出反应?

您最好的选择是选择公共基类 - System.Xml.XmlNode,或者创建两个单独的界面,一个使用XmlAttribute,另一个使用XmlElement

例如:

public interface ICommonInterface<T> : IEnumerable
{
    //common things that rely only on the first type go here
}

public interface IAttributeInterface<T, T2> : ICommonInterface<T>
    where T2 : XmlAttribute
{
}

public interface IElementInterface<T, T2> : ICommonInterface<T>
    where T2 : XmlElement
{
}

如果接口的主要目标是在大多数情况下同时使用两种类型的东西,那么您应该使用XmlNode约束或包装类ala Adapter / Facade模式。