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

您通常不能捕获对变量的引用并将其存储为属性。一个骇人听闻的解决方案(并不是真的暗示这是一个好主意,我会先探索其他途径)是在闭包中捕获它并传递闭包。闭包捕获变量,而不是值。因此,可以在其他地方观察到变量的变化。例如,给定

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的变化,因为这是调用者包含在 lambda 中的内容。如果来电者简单地说() => new Foo(),您(当然)不会观察到任何变化。

于 2011-09-06T21:35:02.487 回答