简体   繁体   中英

C# delegate to struct method

I am trying to create a delegate to a struct method for a particular instance. However, it turns out that a new instance of the struct is created and when I call the delegate it performs the method over the newly created instance rather than the original.


static void Main(string[] args)
{
Point A = new Point() { x = 0 };
Action move = A.MoveRight;
move();
//A.x is still zero!
}

struct Point { public int x, y; public void MoveRight() { x++; } }

Actually, what happens in this example is that a new instance of struct Point is created on the delegate creaton and the method when called through the delagate is performed on it.

If I use class instead of the struct the problem is solved, but I want to use a struct. I also know there is a solution with creating an open delegate and passing the struct as the first parameter to a delegate, but this solution seems rather too heavy. Is there any simple solution to this problem?

No, there's no way around this. Do you have a specific reason to use struct ? Unless you have a particular need for it, you really should be using class .

Incidentally, you have created a mutable struct (a struct whose values can change), which is, without exaggeration, anathema. You need to be using a class.

Mutable structs are evil and shouldn't be used!*

You could change your struct to be immutable and your MovePoint method to return a new value of the struct:

struct Point {
    private readonly int x, y;
    public Point(x, y) { 
        this.x = x; this.y = y;
    }

    public struct MoveRight() {
        x++;
    }
}

Then you'd use Func<Point, Point> to represent operation that changes the point:

Func<Point, Point> move = a => a.MoveRight;

Point A = new Point() { x = 0 };
Point newA = move(A);
// newA.x is 1, but A.x is still 0, because struct is immutable
Point anotherA = move(newA);
// move the point again...

*) Sure, there are situations where they may be useful, but if your situation was one of them, you wouldn't be asking this question.

Anathema or not maybe in office use of C#. In 3D engines we do any kind of devil work. So for example in Unity3D engine Vector3 is struct by you have function Set(x,y,z) and you can even change x,y,z as they are public fields. Everything for speed(eg if you have less calculation for this, you will have for something else.

  static void Main(string[] args)
    {
    Point A = new Point() { x = 0 };
    MyPointDelegate<Point> move=(ref Point p)=> p.MoveRight();
    move(ref A);
    Console.Write(A.x);
    //A.x is one!
    }



public delegate void MyPointDelegate<Point>(ref Point t);

struct Point
{
    public int x, y;

    public void MoveRight()
    {
        x++;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM