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

Output:

1: 0; 0

2: 0; 0

3: 50; 50

What I expected:

1: 0; 0

2: 50; 50

why does rect.Offseted(50, 50) not modify the x and y of the rectangle in step 2?

What do I have to do with my RectangleExtension method to get my expected result?

Felix
  • 71
  • 8

1 Answers1

2

The answer is: structs are always passed by value in C#, and Rectangle in your case is a struct, not a class.

Try this:

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();
    }
}
kevin
  • 2,196
  • 1
  • 20
  • 24
  • 1
    This is just one example why many people say [mutable structs are evil](http://stackoverflow.com/questions/441309/why-are-mutable-structs-evil). It is not related to this being an extension method. The same would happen with a usual method, where `rect` is a value parameter. The type [`System.Drawing.Rectangle`](http://msdn.microsoft.com/en-us/library/system.drawing.rectangle.aspx) was designed (for .NET 1.0) as an evil struct. Also try `list[0].Offset(50, 50);` where `Offset` is the instance method in `Rectangle` (shipped with BCL), and `list` is a `List`. `List<>` has an indexer. – Jeppe Stig Nielsen Mar 30 '14 at 19:56