2012-03-06 43 views
1

我是C#中的新成員。我來自Java世界。所以我很困惑與下面的代碼:通過引用檢索屬性

class A 
    { 
     private PointF point; 

     public A(PointF point) 
     { 
      this.point = point; 
     } 

     public PointF Position 
     { 
      get { return point; } 
     } 
    } 

我想改變位置屬性的X座標,所以我執行:

 A a = new A(new PointF(1,2)); 
     PointF p = a.Position; 
     p.X = 100; 
     Console.WriteLine(a.Position.X); // <--- I have 1 here! 

我不知道爲什麼輸出不是?據我瞭解,我收到了有Position屬性的私人領域的參考。我對嗎?

我可以進行變更而增加一套屬性和傳播位置的PointF對象的屬性?

+2

不,你不能。由於PointF是結構,它是值類型。 – Disposer 2012-03-06 13:10:36

+0

是的,你可以。你可以粘貼你的PointF的代碼,我認爲PointF.X上的setter沒有做它應該做的事情。 - 編輯:哦,我沒有意識到PointF是一個結構,而不是一個類...所以你的'p'變量是從a.Position複製一個全新的結構。如果您希望將其作爲參考,則必須將PointF封裝在類中或將新類型定義爲類。或者你可以使用Point類。 – 2012-03-06 13:12:20

+0

你確定嗎?我測試了它的工作。你也可以在你的示例中添加PointF類。編輯:哈哈我沒有看到struc都不 – Guillaume 2012-03-06 13:14:43

回答

6

沒有傳遞參數; PointFstruct,所以它具有複製語義,並且不是對象;只要你獲得它 - 它是一個單獨的和孤立的副本(除非你使用像ref/out,這是...更微妙)。在你的例子中,結構實際上被複制了多次。

順便說一句,這樣做的結果是,它實際上是一個非常糟糕的主意,有可變的結構 - 因此在大多數情況下,你應該避免的情況下,你可以說:

p.X = 100; 

,因爲這會導致比它幫助更多的困惑。特別是以下是完全無效:

a.Position.X = 100; // won't even compile 

(這裏的編譯是察覺你正在改變,只有突變本身,這意味着你的改變去無處過程中存在的結構的副本,並且幾乎是肯定是一個bug)

0

你需要使用保存的話說出來(功能)和REF(當發送到功能)參照

+0

傳遞一個結構通過引用不會讓你*存儲*引用;它將在分配給任何東西時被解除引用。 – 2012-03-06 13:18:00

2

PointF是一個Struct。在.Net Framework結構中,爲valueTypes。因此,您的示例將始終打印出1.

您在課堂中使用它並不重要。每次給一個值類型的變量賦值時,的值將被複制到

+1

你的意思是它總是會打印出1,而不是100. – 2012-03-06 13:12:24

+0

thx的提示,編輯我的答案 – 2012-03-06 13:14:34

2

PointF是具有所有後果的值類型。 如果要更改屬性中PointF值的唯一「X」屬性,則需要將值複製到變量中,更改「X」屬性並設置屬性的更改值。

var cls = new A(); 
var point = cls.Point; 
point.X = 15; 
cls.Point = point; 
0

我想知道爲什麼你的編譯器不會給你一個警告。 這裏發生的事情是你沒有返回一個PointF引用,它大概是一個值類型,實際上你是返回一個副本。然後您修改該副本的X屬性。當然這不能工作。

+0

這不是一個錯誤(儘管它是不可取的),因爲你仍然可以做一些有趣的變異本地副本。當您直接在屬性獲取中嘗試此操作時出現錯誤的時間。 – 2012-03-06 13:16:59

+0

@MarcGravell當然,你是對的。 – dowhilefor 2012-03-06 13:23:39

0

在你的例子中,pa是兩個不同的對象,所以改變前者不會影響後者。

+1

p不是一個對象*根本就不是* – 2012-03-06 13:17:13

0

在C#中,你有properties

class A 
{ 
    public PointF Position {get;set;} 

    public A(PointF point) 
    { 
     this.Position = point; 
    } 
} 

A a = new A(new PointF(1,2));  
    a.Position.X = 100 
    Console.WriteLine(a.Position.X); 
+0

由於'PointF'是一個'struct',所以它不會編譯;你不能通過'get'來改變'struct' – 2012-03-06 13:20:27

2

在C#中,有兩種類型的變量 - 值類型和引用類型。當分配值類型時,它們被複制 - 對於參考類型,將複製參考

Point是一個值類型(struct)和賦值得到複製。所以:

PointF p = a.Position; 

p複製的a.Position,從它完全獨立。所以:

p.X = 100; 

修改的Xp的價值,留下a.Position.X不變。