C#按值/按引用传递+扩展方法

3
public static class RectangleExtension
{
    public static Rectangle Offseted(this Rectangle rect, int x, int y)
    {
        rect.X += x;
        rect.Y += y;
        return rect;
    }
}


....

public void foo()
{
    Rectangle rect;

    rect = new Rectangle(0, 0, 20, 20);
    Console.WriteLine("1: " + rect.X + "; " + rect.Y);

    rect.Offseted(50, 50);  
    Console.WriteLine("2: " + rect.X + "; " + rect.Y);

    rect = rect.Offseted(50, 50); 
    Console.WriteLine("3: " + rect.X + "; " + rect.Y);
}

输出结果:
1: 0; 0
2: 0; 0
3: 50; 50
我的期望结果:
1: 0; 0
2: 50; 50
为什么在第二步中rect.Offseted(50, 50)没有修改矩形的x和y值?
我需要对我的RectangleExtension方法进行何种修改才能得到期望的结果?

(ref rect)。Offseted(50,50); - Rand Random
1个回答

2
答案是:在C#中,structs始终按值传递,而在您的情况下,Rectangle是一个struct,而不是class

尝试这个:

public class A {
    public int x;
}
public struct B {
    public int x;
}
public static class Extension {
    public static A Add(this A value) {
        value.x += 1;
        return value;
    }
    public static B Add(this B value) {
        value.x += 1;
        return value;
    }
}
class Program {
    static void Main(string[] args) {
        A a = new A();
        B b = new B();
        Console.WriteLine("a=" + a.x);
        Console.WriteLine("b=" + b.x);
        a.Add();
        b.Add();
        Console.WriteLine("a=" + a.x); //a=1
        Console.WriteLine("b=" + b.x); //b=0
        Console.ReadLine();
    }
}

1
这只是为什么许多人说mutable structs are evil的一个例子。这与它是扩展方法无关。在rect是值参数的常规方法中,同样会发生这种情况。类型System.Drawing.Rectangle被设计为(针对.NET 1.0)一个邪恶的结构体。还可以尝试list[0].Offset(50, 50);,其中OffsetRectangle中的实例方法(随BCL一起提供),而listList<Rectangle>List<>具有索引器。 - Jeppe Stig Nielsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接