Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#委托给结构方法_C#_Delegates_Struct - Fatal编程技术网

C#委托给结构方法

C#委托给结构方法,c#,delegates,struct,C#,Delegates,Struct,我正在尝试为特定实例创建一个结构方法的委托。但是,结果是创建了一个新的结构实例,当我调用委托时,它会对新创建的实例而不是原始实例执行该方法 静态void Main(字符串[]参数) { 点A=新点(){x=0}; 动作移动=A.向右移动; move(); //A.x仍然是零! } 结构点 { 公共整数x,y; 公权 { x++; } } 实际上,本例中发生的情况是,在委托creaton上创建了一个新的struct Point实例,并且通过delagate调用该方法时会对其执行 如果我使用类而

我正在尝试为特定实例创建一个结构方法的委托。但是,结果是创建了一个新的结构实例,当我调用委托时,它会对新创建的实例而不是原始实例执行该方法


静态void Main(字符串[]参数)
{
点A=新点(){x=0};
动作移动=A.向右移动;
move();
//A.x仍然是零!
}

结构点 { 公共整数x,y; 公权 { x++; } }
实际上,本例中发生的情况是,在委托creaton上创建了一个新的struct Point实例,并且通过delagate调用该方法时会对其执行


如果我使用类而不是结构,问题就解决了,但我想使用结构。我还知道有一种解决方案,可以创建一个开放委托,并将结构作为第一个参数传递给委托,但这种解决方案似乎太重了。这个问题有什么简单的解决办法吗?

没有,没有办法解决。您是否有使用
struct
的特定原因?除非您有特殊需要,否则您确实应该使用
class


顺便说一句,您已经创建了一个可变结构(其值可以更改的结构),毫不夸张地说,这是一种诅咒。您需要使用类。

可变结构是邪恶的,不应该使用*

您可以将
struct
更改为不可变,并将
MovePoint
方法更改为返回struct的新值:

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

    public struct MoveRight() {
        x++;
    }
}
然后使用
Func
表示更改点的操作:

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...
Func move=a=>a.MoveRight;
点A=新点(){x=0};
点newA=移动(A);
//newA.x是1,但A.x仍然是0,因为struct是不可变的
点anotherA=移动(newA);
//再次移动该点。。。


*)当然,有些情况下它们可能有用,但如果你的情况是其中之一,你就不会问这个问题。

诅咒与否也许在办公室使用C#。在3D引擎中,我们做任何类型的魔鬼工作。例如,在Unity3D引擎中,Vector3是由函数集(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++;
    }
}
static void Main(字符串[]args)
{
点A=新点(){x=0};
MyPointDelegate move=(参考点p)=>p.MoveRight();
移动(参考A);
控制台写入(A.x);
//A.x是一个!
}
公共委托无效MyPointDelegate(参考点t);
结构点
{
公共整数x,y;
公权
{
x++;
}
}

嗯,他的结构是一个2D点,只包含8个字节,因此他可能有一个很好的理由。同时,称可变结构为anathema可能有点夸张。在XNA/C#中为Xbox 360开发时,有时可变结构是您快速代码的唯一选项(因为Xbox使用紧凑的CLR)@TheBigO:我承认存在适合可变结构的情况,但我愿意说,如果有人问这样关于结构的问题(这表明对于这种开发至关重要的值类型语义的复杂性,OP并不清楚)然后这是他们应该绝对避免的事情。
=>
操作符在这种情况下做了什么?@TheBigO:它是lambda函数的声明-它创建一个以
为参数的委托,调用其
MoveRight
方法并返回结果。(搜索C#3.0 lambda语法)如果这是真正对性能敏感的代码,并且您需要结构,那么请避免完全使用委托。如果您尚未分析此代码,甚至不知道此代码是否会成为瓶颈,则只需使用类或将结构作为参数传递给委托即可。
  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++;
    }
}