C # делегат для структурного метода - PullRequest
4 голосов
/ 23 февраля 2011

Я пытаюсь создать делегата для метода struct для конкретного экземпляра.Однако оказывается, что создается новый экземпляр структуры, и когда я вызываю делегата, он выполняет метод над вновь созданным экземпляром, а не над оригиналом.


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

struct Point
{
    public int x, y;

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

Собственно, что происходитв этом примере создается новый экземпляр структуры Point на делегате creaton, и на нем выполняется метод, вызываемый через делагат.

Если я использую класс вместо структуры, проблема решена, ноЯ хочу использовать структуру.Я также знаю, что есть решение с созданием открытого делегата и передачей структуры в качестве первого параметра делегату, но это решение кажется слишком тяжелым.Есть ли простое решение этой проблемы?

Ответы [ 3 ]

8 голосов
/ 23 февраля 2011

Нет, тут нет пути.У вас есть конкретная причина для использования struct?Если у вас нет особой необходимости в этом, вы действительно должны использовать class.

Кстати, вы создали изменчивую структуру (структуру, значения которой могут изменяться), которая без преувеличения является анафемой.Вы должны использовать класс.

6 голосов
/ 23 февраля 2011

Изменяемые структуры являются злом и не должны использоваться! *

Вы можете изменить свой struct на неизменяемый и метод MovePoint, чтобы он возвращал новое значение структуры:

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

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

Тогда вы будете использовать Func<Point, 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...

*) Конечно, есть ситуации, когда они могут быть полезны, но если бы ваша ситуация была одной из них, вы бы не задавали этот вопрос.

1 голос
/ 28 мая 2019

Анафема или нет, возможно, в офисе использование C #.В 3D движках мы выполняем любую дьявольскую работу.Так, например, в движке Unity3D Vector3 имеет структуру с помощью функции Set (x, y, z), и вы даже можете изменить x, y, z, так как они являются открытыми полями.Все для скорости (например, если у вас меньше расчетов для этого, у вас будет для чего-то еще.

  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++;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...