0

インデクサーを備えた次の C# ジェネリック クラスがあります。

public class MySpecializedContainer<T> where T : new()
{
    private InternalContainer<Element> container;
    public T this[int index]
    {
        set 
        {
            ConvertTToElement( value, container[index] );
        }
        get
        {
            T obj = new T();
            Element elem = container[index];
            ConvertElementToT( elem, obj );
            return obj;
        }
    }
}

ご覧のとおり、私のクラスは、Element の内部コンテナーが T のコンテナーであると見なします。これは、Element を T に、またはその逆に変換できる限り機能します。

これに関する問題は次のとおりです。

以下は、内部コンテナー内の実際の要素を効果的に変更するため、期待どおりに機能します。

public class MyClass {
   public int a ;
}
MySpecializedContainer<MyClass> container = ...;
MyClass temp = container[18];
temp.a = 5;
container[18] = temp;

しかし、この単純なバージョンでは次のことはできません:

container[18].a = 5;

これは、getアクセサーがインデクサーで作成したコピーを変更するだけです...

これを機能させる方法はありますか?

そうでなければ、少なくともこのステートメント「container[18].a=5」をコンパイルしないようにする解決策がありますが、代わりにそれをサポートしたいと思います。

ありがとう

4

2 に答える 2

1

いいえ、それは不可能です (既存のコードの動作に大きな変更がなければ)。

これを機能させるには、MyClass返されるインスタンスが、いつ変更されたかを認識し、それが発生したときに基礎となるものを更新できるほどスマートである必要がありますElement。これは可変フィールドでは不可能です。それが仮想プロパティである場合は、ショットがあります。

次のように変更するMyClassと:

public class MyClass 
{
   public virtual int a {get;set;}
}

次に、コンテナー内に特別なサブクラスを作成できます。

public class MySpecializedContainer<T> where T : new()
{
    private class MySubClass : MyClass
    {
        private Element wrappedElement;
        public MySubClass(Element wrappedElement)
        {
            this.wrappedElement = wrappedElement;
        }
        public override int a
        {
            set
            {
                base.a = value;
                wrappedElement.Update(value);
            }
        }
    }
}

ConvertElementToTの新しいインスタンスを作成MySubClassして適切なElementオブジェクトを渡すように、それに応じて も更新する必要があります。

したがって、ここでの教訓は、パブリック フィールドを使用しないことです。

于 2013-01-31T22:40:00.647 に答える
1

Elementと の間に参照変換がある場合にのみ、本当にやりたいことができますT。次に、インデクサーで、にキャストされた内部オブジェクトへの参照を返すことができますT

于 2013-01-31T22:31:02.467 に答える