使用ref关键字保存对象引用以供将来使用

本文关键字:将来 对象引用 ref 关键字 保存 使用 | 更新日期: 2023-09-27 18:07:40

假设我有一个简单的类:

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?
}

使用ref关键字保存对象引用以供将来使用

听起来你在寻找TypedReference__makeref关键字。

警告:它们的文档记录很差,不在c#的标准化部分。

这个问题有很多信息

c#中的所有类都是引用对象,所以您编写的代码应该更新SavedElement的值。然而,如果T是一个基本类型(例如,int, string等),这将不起作用,因为它们是按值设置的。您需要在T上设置约束,以确保它是一个类。

通常不能捕获对变量的引用并将其作为属性存储。一个简单的解决方案(并不是说这是个好主意,我想先探索一下其他方法)是在闭包中捕获它,然后传递闭包。闭包捕获变量,而不是值。因此,可以在其他地方观察到对变量的更改。例如,给定

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(),您(当然)不会观察到任何变化。