Reputation: 671
My problem, narrowed down to a simple explaination, is the following: I have a class which needs to work with a number (without changing it) which is subject to change. This number doesn't necessarily come from another class, and it can be anything. But I'd like to only "give" it to the class once, instead of constantly having to call update methods or having to create a wrapper (since again, as I said, this should work with any kind of number and having to wrap up everything is kind of unpratical).
Here's some code, hoping it helps:
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();
}
}
Now, the problem seems pretty obvious: If I instantiate a SimpleExample and give it a variable as a parameter, it will get its value rather than a reference to it. Is there a simple enough way that can avoid me the creation of a wrapper? Thanks.
Upvotes: 2
Views: 2562
Reputation: 81143
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.
Upvotes: 1
Reputation: 79441
Make a really simple class:
class Ref<T>
{
public T Value;
public Ref<T>()
{
}
public Ref<T>(T value)
{
this.Value = value;
}
}
Then use it like this:
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);
Note that the Ref<T>
class here is a reference to a value - not a reference to a variable. If you want a reference to a variable, use Eric Lippert's solution (as pointed out by Filip).
Upvotes: 7
Reputation: 203821
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();
}
}
Upvotes: 4