tags:

views:

183

answers:

6
void Afunction(int* outvar)
{
    if(outvar)
        *outvar = 1337;
}

note the qualities: it allows you to optionally pass a variable by reference, so that it can be set by the function.

my closest guess would be (ref int? outvar)

but that produces ref (int?) NOT (ref int)? which is what I need

this functionality is hardly a scarcely used feature of c or c++, so I assume there must be some equivalent? Edit: so let me try a good example, I think a Colision check function is a prime example, where you have the primary test being whether or not two objects are in contact, then the optional output of the projection vector, calculating the projection vector takes extra time, so you only want to do it if they want it, on the other hand, it usually uses alot of the info calculated when doing the collision test.

bool Collide(colObject obj1, colObject obj2, Vector3* projection)
{

    //do a bunch of expensive operations to determine if there is collision
    if(!collided)return false;
    if(projection != NULL)
    {
        //do more expensive operations, that make use of the above operations already done,
        //to determine the proj vect
        *proj = result;
    }
    return true;
}

note that I am currently just porting c++ code to c#, so I might not have though of any real 'out of the box' solutions

A: 

Try the out keyword.

void Afunction(out int outvar) {
    outvar = 1337;
}

It is not exactly equivalent. For example, you must assign a value to an out argument unless you throw from the function.

Duracell
the key word there is 'optional' sometimes I don't need the outvar, so in c I would just pass null, this allows the function to know whether the outval is even needed, and can therefore skip a whole bunch of calculation if it isn't
matt
+1  A: 

I can't think of a direct translation of that C code. I think the C# paradigm looks more like this:

void Afunction()
{
}

void Afunction(out int outvar)
{
    Afunction();
    outvar = 1337;
}
Daniel Stutzbach
He wants to be able to skip the calculation.
SLaks
@SLaks: Put the calculation in `Afunction(out int outvar)`. Put anything that doesn't get skipped (if anything) in `Afunction()`.
Daniel Stutzbach
+5  A: 

The best you can get in C# is Action<int>, like this:

void MyFunction(Action<int> valueReceiver) {
    if (valueReceiver != null)
        valueReceiver(1337);
}

Usage:

MyFunction(null);
MyFunction(v => someVariable = v);
SLaks
`Func<int>` is for a function that will return an int and take no parameters. What you want is `Action<int>` which takes an int and has no return value
Grant Peters
@Grant - 18 minutes for someone to notice? I think we are slipping.
ChaosPandion
@Grant, @ChaosPandion: Thanks; I need more sleep.
SLaks
not as pretty as I might like, but it will do! thanks!
matt
+1  A: 

I think ref is more in line with the intent of the C code:

void Afunction(ref int refvar) { 
    refvar = 1337; 
} 

But you can also resort to unsafe:

unsafe void Afunction(int* pvar) {
  if (pvar != null) {
    *pvar = 1337;
  }
}  
Jordão
I'm going to assume that unsafe code isn't supported on windows phone 7?
matt
And you would be [right](http://stackoverflow.com/questions/1307012/net-micro-framework-unsafe-code/1307031#1307031).
Jordão
+3  A: 

Isn't this what you want?

private void foo()
{
    int? y = 0;
    bar(ref y);

    int? z = null;
    bar(ref z);

    // shows "y = 42, z = "
    MessageBox.Show(string.Format("y = {0}, z = {1}", y, z));
}

private void bar(ref int? varRef)
{
    if (varRef != null)
        varRef = 42;
}
egrunin
I also though that this would be pretty close. Although it is a bit clunky.
ChaosPandion
+4  A: 

It depends on what you want to use that pointer for in C++. There are four things you can use a pointer for:

  1. Setting the value of the variable pointed to by the pointer.
  2. Fetching the value of the variable pointed to by the pointer.
  3. Comparing the pointer itself to null
  4. Comparing the pointer itself to another pointer.

If you want to do the first one, make it an "out" parameter.

If you want to do the first two, make it a "ref" parameter.

If you want to do the first three, then what I usually do in this unfortunate situation is:

sealed class Ref<T>
{
    private Action<T> setter;
    private Func<T> getter;
    public Ref(Action<T> setter, Func<T> getter) 
    {
        this.setter = setter;
        this.getter = getter;
    }
    public T Value { get { return getter(); } set { setter(value); } }
}

and now you can say

void M(Ref<int> r)
{
    if (r != null) // 3
    {
        Console.WriteLine(r.Value); // 2
        r.Value = 123; // 1
    }
}
...
int x = 0;
M(new Ref<int>(y=>{x=y;}, ()=>x); // pass a 'ref' to x

Then I refactor the code so that I am not in a situation where I have to pass something for the express purpose of mutating it.

Alternatively, a bit simpler but less flexible about where the variable is stored:

class Ref<T>
{
    public T Value { get; set; }
}
... M same as before ...
Ref<int> x = new Ref<int>();
x.Value = 0;
M(x); 

With the delegate scheme you get added flexibility because the delegates can of course do more complex things than just getting and setting variables.

If you want all four: use C++, not C#, or use the unsafe subset of C# and stick with pointers. There's no easy way to compare references to each other in normal C#.

Eric Lippert