2

我的问题,缩小为一个简单的解释,如下所示:我有一个类需要处理一个可能会发生变化的数字(不改变它)。这个数字不一定来自另一个班级,它可以是任何东西。但是我只想将它“给”一次类,而不是不断地调用更新方法或必须创建一个包装器(再次,正如我所说,这应该适用于任何类型的数字并且必须包装一切都是不切实际的)。

这是一些代码,希望对您有所帮助:

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

4

3 回答 3

7

制作一个非常简单的类:

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 所指出的)。

于 2013-04-19T17:30:42.717 回答
4

So what you want is not an int, but rather a way of getting an int at some point in time. There are several ways of doing this, one of which is to have your object accept a Func<int>. Then the code can pass in a method that returns the current value of...whatever, rather than the value at the time SimpleExample is created. Using a lambda to close over a variable makes doing this much easier as well.

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();
    }
}
于 2013-04-19T17:32:00.740 回答
1

There is no standard wrapper for the purpose you seek, though a single-element array could be used for that purpose. Alternatively, one could define a simple wrapper type:

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

and then use an ExposedValueHolder<YourStructType> to wrap your object. It's not possible in general to capture something passed as an arbitrary ref parameter, since objects may live indefinitely but byrefs (the things which are actually passed when using ref parameters) may die any time after function they're passed to goes out of scope.

于 2013-04-19T17:49:23.157 回答