0

C# のジェネリックのワイルドカードで問題が発生しました。私の小さな例を実行するための最初のアプローチは、すべての基本クラスであるため、オブジェクトをジェネリック型として使用することでした。

   public class AttributeManager
    {

        private Dictionary<int, AttributeItem<object>> attributes = new Dictionary<int, AttributeItem<object>>();

        public void add(AttributeItem<object> attribute)
        {
            if (hasAttribute(attribute)) {
                return;
            }
            attributes.Add(attribute.getKey(), attribute);
        }
    }

public abstract class AttributeItem<T>
{
    private int key;
    private T attributeValue;
    private AttributeManager attributeManager;

    public AttributeItem(AttributeManager attributeManager, int key)
    {
        this.key = key;
        this.attributeManager = attributeManager;
        attributeManager.add(this); // this line does not work
    }

    public void setValue(T newValue)
    {
        attributeValue = newValue;
    }

    public T getValue()
    {
        return attributeValue;
    }
}

ただし、次の行:

attributeManager.add(これ);

動作しません。この呼び出しでオーバーロードされたメソッドが見つからなかったと表示されます。オブジェクトは T のスーパークラスでなければならないため、「this」は AttributeItem にキャストされると思いました。最初の質問は、なぜこのキャストが機能しないのかということです。

私の 2 番目のアプローチは、ワイルドカードの種類を使用するように AttributeManager を変更することでした。

   public class AttributeManager
    {

        private Dictionary<int, AttributeItem<????>> attributes = new Dictionary<int, AttributeItem<????>>();

        /**
         * This method will add a new AttributeItem if hasAttribute(AttributeItem) returns false.
         */
        public void add<T>(AttributeItem<T> attribute)
        {
            if (hasAttribute(attribute)) {
                return;
            }
            attributes.Add(attribute.getKey(), attribute); // this line fails
        }

    }

しかし、ご覧のとおり、宣言で渡さなければならない型がわかりません。

Dictionary<int, AttributeItem<????>> attributes

2 番目の質問は、????? の代わりに何を使用すればよいかということです。

よろしくロバート

4

3 に答える 3

2

最も簡単な解決策は、プライベート ディクショナリ フィールドのレベルでジェネリックを取り除くことです。

private Dictionary<int, object> attributes = new Dictionary<int, object>();

そうすれば、クラスには優れたジェネリック インターフェイスがあり、ジェネリック Manager インスタンスは必要ありません。

難しいのは、後で辞書から有用なものを取得することです。リフレクションを使用することもできますが、Onam と Robert Hahn によって提案されているインターフェイス手法を使用することをお勧めします。これで問題が解決しない場合は、ユースケースについて詳しく教えてください。

于 2013-07-08T14:17:23.570 に答える