开发者

what is the equivalent to passing by address in c#

开发者 https://www.devze.com 2023-01-07 18:55 出处:网络
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.
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;
    }
   开发者_StackOverflow 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


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);


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#.


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;
}


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;
}


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;
  }
}  


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.


I guess one thing you could do is make 2 proxy functions that call a hidden function and just appending an extra parameter to tell the hidden function what is happening.

E.g.

private bool Collide(colObject obj1, colObject obj2, ref Vector3 projection, bool calcProjection)
{

    //do a bunch of expensive operations to determine if there is collision
    if(!collided)return false;
    // Now instead of checking if projection is null, we just check if they requested it
    if(calcProjection)
    {
        //do more expensive operations, that make use of the above operations already done,
        //to determine the proj vect
        *proj = result;
    }
    return true;
}

public bool Collide(colObject obj1, colObject obj2, ref Vector3 projection)
{
    return Collide(obj1, obj2, ref projection, true);
}

public bool Collide(colObject obj1, colObject obj2)
{
    Vector3 dummy;
    return Collide(obj1, obj2, ref dummy, false);
}

Not sure how well this will perform compared to the other answers here, but seeing how most of them create intermediary objects, it SHOULD be comparable.

0

精彩评论

暂无评论...
验证码 换一张
取 消