使用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?
}
听起来你在寻找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()
,您(当然)不会观察到任何变化。