0

ジェネリック型の許可された型として設定しようとしてXmlAttributeXmlElementますが、両方を同時に設定すると、コンパイル中にエラーが発生します:

クラス型制約 'System.Xml.XmlElement' は、他の制約よりも前に指定する必要があります

コードの例:

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

このような制約を設定できないのはなぜですか?

4

4 に答える 4

3

使用している制約は、許可されている型のリストを表していません。これは、「 に挿入されたものはすべてT2から継承する必要がある」ことを意味します。

これは、挿入されたものT2はすべて、特定のパブリック インターフェイス (プロパティとメソッド)、つまり指定された型から継承されたものを提供することをコンパイラが確認できるようにするためです。そこに複数の選択肢を挙げることができるとしたら、どのインターフェースが当然と見なされますか? 挿入される内容に応じて、が提供するすべてのメソッドとプロパティ、またはT2が提供するすべてのメソッドとプロパティのいずれかを持つことができますが、いずれも確実ではありません。XmlAttribute XmlElement

于 2013-07-31T10:22:45.787 に答える
1

コンマで区切られた複数の制約をリストすると、C# は* これらの制約のいずれかではなく、すべてTを満たす必要があることを伝えます。2 つのクラスのいずれかでなければならないという制約を作成することはできません。型パラメーターを制約することで、許容される操作とメソッド呼び出しの数を、型制約としてリストした制約型とすべてのインターフェイスでサポートされているものに増やします。それが、そもそも型クラスベースおよびインターフェイスベースの制約を持つ目的であり、クラスでサポートされているものを超えて操作を呼び出すことができます。TSystem.Object

結果として、制約のリストに 2 つのクラスを入れることは決してありません (ただし、もちろん、クラスと必要な数のインターフェースを入れることができます)。2 つのクラスが関連している場合でも、最も派生したクラスを制約に入れることは、両方を入れることと同じです。

于 2013-07-31T10:24:53.900 に答える
0

と の間のカンマは、またはではなく、XmlAttribute意味XmlElementすることに注意してください。とはクラスであり、C# には多重継承がないため、ジェネリック パラメーターが制約を満たすことは不可能です。XmlAttributeXmlElement

于 2013-07-31T10:22:35.133 に答える
0

これができないのは、2 つの型のメンバーが異なるためです。メソッドでこれを使用することを考えてみてください。体内で何が起こるでしょうか? 渡される型を知らずにメソッドを作成するにはどうすればよいでしょうか? オートコンプリートはこの種の制約にどのように反応しますか?

あなたの最善の策は、共通の基本クラス - を選択するか、System.Xml.XmlNodeおそらく 2 つの別個のインターフェースを作成する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アダプター/ファサード パターンの制約またはラッパー クラスを使用する必要があります。

于 2013-07-31T10:24:11.390 に答える