说我有一个像这样的简单类:
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?
}
答案 0 :(得分:4)
答案 1 :(得分:0)
C#中的所有类都是引用对象,因此您编码的内容应更新SavedElement
的值。但是,如果T
是基本类型(例如,int,string等),则这不起作用,因为它们是按值设置的。您需要在T
上设置约束以确保它是一个类。
答案 2 :(得分:0)
您通常无法捕获对变量的引用并将其存储为属性。一个hackish解决方案(并不是真的暗示这是一个好主意,我首先探索其他途径)是在一个闭包中捕获它并传递闭包。闭包捕获变量,而不是值。因此,可以在其他地方观察变量的变化。例如,给定
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()
,你(当然)不会观察到任何变化。