c# -通过引用传递值类型的好而灵活的方法

本文关键字:方法 类型 -通 引用 | 更新日期: 2023-09-27 18:10:07

我的问题,归结为一个简单的解释,是:我有一个类,需要与一个数字工作(不改变它),这是可能发生变化。这个数不一定来自其他类,它可以是任何数。但是我想只"给"它一次给类,而不是不断地调用更新方法或创建包装器(因为,正如我所说的,这应该与任何类型的数字一起工作,而必须包装所有东西是不切实际的)。

下面是一些代码,希望能有所帮助:

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并给它一个变量作为参数,它将获得它的值,而不是对它的引用。是否有一种足够简单的方法可以避免创建包装器?谢谢。

c# -通过引用传递值类型的好而灵活的方法

创建一个非常简单的类:

class Ref<T>
{
    public T Value;
    public Ref<T>()
    {
    }
    public Ref<T>(T value)
    {
        this.Value = value;
    }
}

然后像这样使用:

class A
{
    Ref<int> x;
    public A(Ref<int> x)
    {
        this.x = x;
    }
    public void Increment()
    {
        x.Value++;
    }
}
...
Ref<int> x = new Ref<int>(7);
A a = new A(x);
a.Increment();
Debug.Assert(x.Value == 8);
注意,这里的Ref<T>类是对的引用,而不是对变量的引用。如果您想要一个变量的引用,请使用Eric Lippert的解决方案(由Filip指出)。

所以你想要的不是整型,而是在某个时间点获得整型的方法。有几种方法可以做到这一点,其中一种方法是让对象接受Func<int>。然后代码可以传入一个方法,该方法返回…的当前值。而不是创建SimpleExample时的值。使用lambda来关闭变量也会使这一工作变得容易得多。

public class SimpleExample
{
    Func<int> func;
    public SimpleExample(Func<int> 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();
    }
}

对于您所寻求的目的,没有标准的包装器,尽管可以使用单元素数组来实现该目的。或者,可以定义一个简单的包装器类型:

public class ExposedValueHolder<T> { public T Value; } // Really simple class, eh?

,然后使用ExposedValueHolder<YourStructType>来包装您的对象。一般来说,捕获作为任意ref参数传递的东西是不可能的,因为对象可能无限期地存在,但byrefs(使用ref参数时实际传递的东西)可能会在传递给超出作用域的函数后的任何时间死亡。