2010-01-17 53 views
3

說我有一個類中的屬性:C#的getter/setter問題

Vector3 position{get; set;} 

所以我的地方創建一個類的實例,現在我想改變position.x,那現在因爲是不可能的getter和setter設置並獲取整個對象。所以我必須做一個臨時的Vector3改變它的值,然後分配它。

通常情況下,我會讓位置成爲公共領域,以便問題得到解決。但我不能這樣做,因爲位置是一個接口的實現,接口不能有字段。

那麼我該如何解決這個最好的方法。

編輯:的Vector3是一個結構所以它的值類型

回答

5

IMO,最簡單的答案在這裏:

private Vector3 position; 
public Vector3 Position { 
    get {return position;} 
    set {position = value;} // with @Mehrdad's optimisation 
} 
public float X { 
    get {return position.X;} 
    set {position.X = value;} 
} 
public float Y { 
    get {return position.Y;} 
    set {position.Y = value;} 
} 
public float Z { 
    get {return position.Z;} 
    set {position.Z = value;} 
} 

現在你可以改變obj.Xobj.Yobj.Z,如果你只需要改變一個維度,或更改obj.Position改變一切。

如果你需要的名字position實現一個接口,然後執行它明確:

Vector3 IWhateverInterface.position { 
    get {return position;} 
    set {position = value;} 
} 
+0

是的,這是我的想法,但就像我在上面的評論中解釋的位置將被修改分配,所以這是最有效的方式?閱讀答案,我認爲這是唯一的方法,我是對的嗎? – slayerIQ 2010-01-17 22:40:20

+1

這與提供方法基本相同。可能的微優化是避免使用'Position'的自動屬性並直接修改'X'屬性中的'position.X'。 – 2010-01-17 22:41:48

+0

@slayerIQ你必須選擇你的戰鬥。如果這是問題,你可以*只暴露'position'作爲字段,並根據我在最後添加的位做顯式接口實現? – 2010-01-17 22:42:27

2

這與可變的值類型的問題之一。您可以使用新的X值創建值類型的新實例,然後重新分配到該屬性。通過提供有用的構造函數或添加返回修改對象的方法(而不是修改該值),可以使實例創建更容易。

+0

問題是,位置將被改變分配。因此,每次我想修改屬性時創建一個新實例或調用一個方法都會過度。 – slayerIQ 2010-01-17 22:26:11

+0

@slayerIQ:你不能在界面中修改它。要麼你不得不使'Vector3'成爲一個類(這可能不是理想的),或者提供修改接口位置的方法(例如'MoveHorizo​​ntally(float distance)'),或者讓客戶端將屬性分配爲'obj.Position = new Vector3(obj.Position.X + 10,obj.Position.Y,obj.Position.Z);'。這個問題並沒有一個更好的解決方案(典型的例子是具有'Control'類的'Location'和'Size'屬性的Windows窗體)。 – 2010-01-17 22:29:08

+0

slayerIQ從未說過Vector3是一個值類型。事實上,這個帖子說它是一個類。這是否是一個錯字還不清楚。 – Eilon 2010-01-17 22:31:05

0

預P.S。看了太晚,Vector3是一個值類型;因此下面的文章不會有太大的幫助。對不起,這個錯誤。

好,而接口不能有田,他們可以有屬性,如:

interface IVector3 
{ 
    double X { get; set; } 
    double Y { get; set; } 
    double Z { get; set; } 
} 

在你Vector3,你只是實現這些和其他事物一樣:

class Vector3 : IVector3 
{ 
    double IVector3.X 
    { 
     get { ... } 
     set { ... } 
    } 
    ... 
} 

現在回到到您的position財產。您在初始化過程中配合的財產,以一個固定的實例,並只提供一個getter:

Vector3 position 
{ 
    get 
    { 
     return _position; 
    } 
} 

private Vector3 _position = new Vector3(...); 

通過使只讀(即沒有setter)的屬性,可以確保它不會用新Vector3更換目的。相反,您可以在初始化時將其與固定實例(_position)綁定。但是,您可以通過將新值分配給position.X,position.Yposition.Z來更改Vector3

+0

另一種方法是定義一個實現IVector3的VectorAccessor類或結構,並持有對具有Vector的主對象的引用。它的X,Y和Z屬性可以訪問MainObject._position.X,等等。如果主類包含一個很大的小結構數組,這將是一個很好的方法。索引器將返回一個VectorIndexer屬性,其XYZ將引用MainObject._positions [Index] .X等。 – supercat 2011-01-27 16:19:17

9

直接的解決方案是不可接受的嗎?

foo.position = new Vector(newX, foo.position.Y, foo.position.Z); 

這是怎麼回事?這看起來非常簡單。