3

次のような単純なクラスがあるとします。

public class ReferenceChanger<T> 
{
    public T SavedElement { get; private set; }

    public ReferenceChanger(T elementToSave)
    {
        SavedElement = elementToSave;
    }

    // This method would change the original variable (given as a constructor argument)
    public void SetNewReference(T newElement)
    {
        SavedElement = newElement;
    }
}

このクラスは、コンストラクターに渡された要素を、その要素が何であれ保存します。ただし、"SavedElement" (そのバッキング フィールド) は、インスタンスの作成時に指定されたオブジェクトへの参照です。

コンストラクターに渡された元のアイテムが変更された場合、オブジェクトが ref キーワードで渡されたかのように、SavedElement が自動的に変更を反映するように、( refキーワードを使用する場合のように)変数への参照を保存する方法はありますか? ? ( refキーワードを使用しても、その方法で参照を保存することはできません。)

意図をより明確にするために更新されました。

public class ExampleClass 
{
    public List<int> Numbers { get; set; }
}

public static void Main()
{
    ExampleClass temp = new ExampleClass();
    temp.Numbers = new List<int>() { 1, 2, 3 }; 

    ReferenceChanger<List<int>> changer = new ReferenceChanger<List<int>>(temp.Numbers);
    // Here, a reference to the List<int> instance (containing 1,2,3) is stored in changer's SavedElement

    // Then I do this:
    changer.SetNewReference(new List<int>() { 5, 6, 7 });

    // Now, only changer's SavedElement was changed, but temp's property Numbers was not changed.
    // Is there a way to change the temp's property Numbers from the changer?
}
4

3 に答える 3

4

TypedReference__makerefキーワードを探しているようですね。

警告: それらは十分に文書化されておらず、C# の標準化された部分ではありません。

この質問にはさらに多くの情報があります。

于 2011-09-06T21:26:43.153 に答える
0

C# のすべてのクラスは参照オブジェクトであるため、コード化したものは の値を更新する必要がありますSavedElement。ただし、Tプリミティブ型 (int、string など) の場合、これらは値によって設定されるため、これは機能しません。Tクラスであることを確認するには、制約を付ける必要があります。

于 2011-09-06T21:16:27.327 に答える
0

通常、変数への参照をキャプチャしてプロパティとして保存することはできません。ハックな解決策の 1 つ (それが良いアイデアだとは言いませんが、最初に他の方法を検討します) は、それをクロージャでキャプチャし、クロージャを渡すことです。クロージャは、値ではなく変数をキャプチャします。その結果、変数の変更は別の場所で観察できます。たとえば、与えられた

class Foo
{
    public int Baz { get; set; }
}

class Bar
{
    private Func<Foo> fooGetter;

    public Bar(Func<Foo> fooGetter)
    {
        this.fooGetter = fooGetter;
    }

    public void Do()
    {
        Console.WriteLine(fooGetter().Baz);
    }
}

あなたが持つことができます

Foo foo = new Foo() { Baz = 1 };
Bar bar = new Bar(() => foo);
bar.Do();
foo = new Foo() { Baz = 2 };
bar.Do();

foo呼び出し元がラムダで囲んだものであるため、変数への変更が監視されます。発信者が単純に と言っていたら、() => new Foo()(もちろん) 変化は見られないでしょう。

于 2011-09-06T21:35:02.487 に答える