2011-02-23 75 views
4

我想創建一個代表特定實例的結構方法。但是,事實證明,結構的新實例已創建,當我調用委託時,它將在新創建的實例上執行該方法,而不是原始方法。C#代理結構方法


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

其實,發生在這個例子中是結構點的新實例是在委託銳創建並在其上執行時,通過delagate調用的方法。

如果我使用類而不是結構該問題已解決,但我想使用一個結構。我也知道創建一個打開的委託並將結構作爲第一個參數傳遞給委託的解決方案,但是這個解決方案似乎太重了。有沒有簡單的解決這個問題?

+1

如果這確實是對性能敏感的代碼,並且您需要結構,那麼請避免完全使用委託。如果您尚未分析此代碼,甚至不知道此代碼是否會成爲您的瓶頸,那麼只需使用一個類或將該結構作爲參數傳遞給代理。 – Olhovsky 2011-02-23 15:10:20

回答

8

不,這是沒有辦法的。你有具體的原因使用struct?除非你有特別需要,否則你應該使用class。順便說一句,你已經創建了一個可變結構(一個結構的值可以改變),這是毫不誇張的詛咒。你需要使用一個班級。

+0

那麼,他的結構是一個2D點,​​只包含8個字節,所以他可能有一個很好的理由。 – Olhovsky 2011-02-23 02:51:38

+1

也調用mutable structs * anathema *可能有點誇張。在XNA/C#中爲Xbox 360開發時,有時可變結構是您快速代碼的唯一選項(因爲Xbox使用緊湊CLR)。 – Olhovsky 2011-02-23 15:12:24

+0

@TheBigO:我會授予存在可變結構適合的情況,但我願意說如果有人問這樣的關於結構的問題(指出錯綜複雜的價值型語義,它們是*至關重要的*對於這樣的發展,對於OP來說是不清楚的),那麼這是他們應該明確避免的。 – 2011-02-23 15:41:34

6

可變的結構是邪惡的,不應該被使用*

你可以改變你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... 

*)當然,有些情況下他們可能會有用,但如果您的情況是其中之一,您不會問這個問題。

+0

在這種情況下,'=>'操作符做了什麼? – Olhovsky 2011-02-23 02:53:12

+0

@TheBigO:它是lambda函數的聲明 - 它創建一個代表'Point'作爲參數的委託,調用它的'MoveRight'方法並返回結果。 (搜索C#3.0 lambda語法) – 2011-02-23 02:54:47