2010-08-24 57 views
1

考慮以下幾點:是可以實現匿名類型的屬性setter方法

var o = new { Foo = "foo", Bar = "bar" }; 

此實例,因爲像類一樣匿名類型沒有實現制定者只讀:

public class O 
{ 
    public String Foo { get; set; } 
    public String Bar { get; set; } 
} 

是否可以「打開」匿名實例並允許其屬性被更改?最好用少於創建課程所需的字符數。

我在想也許這可以用Object上的擴展方法來完成; o.SetProperty(o.Foo, "foo!");,如果你不能在對象的構造中實現聯機的setter。

回答

3

匿名類型是不可變的設計,所以你無法改變他們的狀態。您可以使用反射(正如Mark Gravell所指出的那樣),但是既不是從設計的角度來看,也不是從理想的性能角度出發。

你有多種選擇,以解決此問題:

  • 使用元組,而不是annonymous類型。請注意,它們也是不可變的,但您可以更輕鬆地使用它們來創建像tupleA.WithItem2(newValueForItem2)這樣的方法。類似於string類。
  • 使用自動屬性,通常很簡單
  • 使用重構工具一樣的CodeRush,可以從您的使用情況
+0

關於反射的聲明是無效的:以下工作正常:'var obj = new {id = 1,name =「abc」}; obj.GetType()。GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Single(f => f.FieldType == typeof(int))。SetValue(obj,456); Console.WriteLine(obj.id);' – 2010-08-24 11:33:53

7

不,在C#中導致匿名類型是不可變的設計。

+0

嗯,C#匿名類型是(而且確實產生了「命名」類型編寫自己的「命名」型該問題被標記爲C#)。我只是強調這是特定編譯器的一個特性,而不是「匿名類型」本身。 – 2010-08-24 11:02:35

+0

@Marc:好的,我猜想首先讓匿名類型不可變的原因與他們在LINQ中通常使用的方式有關。 – 2010-08-24 11:04:19

+0

+1謝謝。我已經接受了約翰內斯的更詳細的答案。它涉及幾個備選方案。 – roosteronacid 2010-08-24 11:21:34