为什么可以';t我将XmlAttribute和XmlElement都设置为通用约束

本文关键字:设置 XmlElement 约束 XmlAttribute 我将 为什么 | 更新日期: 2023-09-27 18:25:42

我试图将XmlAttributeXmlElement设置为泛型类型的允许类型,但当我同时设置它们时,我在编译过程中遇到错误:

类类型约束"System.Xml.XmlElement"必须位于任何其他限制

代码示例:

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

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

为什么可以';t我将XmlAttribute和XmlElement都设置为通用约束

您使用的约束不是表示允许的类型列表。这意味着"为T2插入的任何内容都必须继承自。"

这样,编译器就可以确保为T2插入的任何内容都提供了特定的公共接口——属性和方法——即从指定类型继承的那些接口。如果你能列出一个以上的替代方案,哪个接口会被认为是理所当然的?根据插入的内容,T2可以具有XmlAttribute提供的所有方法和属性,也可以具有XmlElement提供的所有方式和属性,但没有一个是确定的。

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

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

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

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

您最好选择公共基类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模式。