C# – 通过引用传递值类型的良好而灵活的方法?
我的问题,缩小到一个简单的解释,如下:我有一个类需要使用一个数字(不改变它),这可能会改变。 这个数字不一定来自另一个类,它可以是任何类。 但是我想只给它一次“给”它一次,而不是经常不得不调用更新方法或者必须创建一个包装器(因为我再说过,这应该适用于任何类型的数字并且必须包装一切都是不合时宜的)。
这是一些代码,希望它有所帮助:
public class SimpleExample { int value; public SimpleExample(int variableOfWhichINeedAReference) { //Of course this won't work, but I'll keep it simple. value = variableOfWhichINeedAReference; } public void DisplayValue() { print(value); } } public class RandomClass { int myValue = 10; SimpleExample s = new SimpleExample(myValue); public void WorkWithValue() { myValue++; } public void Display() { print(foo); print(bar); s.DisplayValue(); } }
现在,问题似乎非常明显:如果我实例化一个SimpleExample并给它一个变量作为参数,它将获得它的值而不是它的引用。 有一种简单的方法可以避免我创建一个包装器吗? 谢谢。
做一个非常简单的课程:
class Ref { public T Value; public Ref () { } public Ref (T value) { this.Value = value; } }
然后像这样使用它:
class A { Ref x; public A(Ref x) { this.x = x; } public void Increment() { x.Value++; } } ... Ref x = new Ref (7); A a = new A(x); a.Increment(); Debug.Assert(x.Value == 8);
请注意,这里的Ref
类是对值的引用 – 而不是对变量的引用。 如果您想要引用变量,请使用Eric Lippert的解决方案 (如Filip所指出的)。
所以你想要的不是一个int,而是一种在某个时间点获取int的方法。 有几种方法可以做到这一点,其中一种方法是让你的对象接受一个Func
。 然后代码可以传入一个返回当前值的方法,而不是当前创建SimpleExample
的值。 使用lambda来关闭变量也可以使这更容易。
public class SimpleExample { Func func; public SimpleExample(Func func) { this.func = func; } public void DisplayValue() { print(func()); } } public class RandomClass { int myValue = 10; SimpleExample s; public RandomClass() { s = new SimpleExample(() => myValue); } public void WorkWithValue() { myValue++; } public void Display() { print(foo); print(bar); s.DisplayValue(); } }
虽然可以使用单元素arrays来实现此目的,但没有标准包装器用于您寻求的目的。 或者,可以定义一个简单的包装器类型:
public class ExposedValueHolder { public T Value; } // Really simple class, eh?
然后使用ExposedValueHolder
来包装您的对象。 一般来说捕获作为任意ref
参数传递的东西是不可能的,因为对象可以无限期地存在但是byrefs(当使用ref
参数时实际传递的东西)可能在传递给它们的函数超出范围之后的任何时间死亡。