2011-02-28 77 views
4

在C#中,我們現在可以使用大括號構造函數構造新的對象,即在C#中,如何使用反射訪問大括號構造函數?

class Person { 
    readonly string FirstName {get; set;} 
    readonly string LastName {get; set;} 
} 

new Person { FirstName = "Bob", LastName = "smith" } 

我需要使用反射來構造這個對象,但是如果這些成員變量標記爲只讀,我只能將它們設置在構造,並且只有可用的花括號構造函數。有什麼方法可以使用反射訪問花括號式構造函數嗎?謝謝。

+11

我甚至不確定你的語法是否正確在你的例子中,只讀屬性? – Pharabus 2011-02-28 19:30:15

+1

@Prabrabus更像是一個只有一個setter的只讀屬性!哈哈哈哈! – Marlon 2012-01-27 07:21:40

回答

23

首先,屬性不能被標記爲只讀與readonly關鍵字。他們只能擁有非公開的setter方法。

其次,沒有「花括號構造函數」這樣的事情。這只是一個syntactic sugar像這樣一組語句(快捷方式):

Person p = new Person(); // standard parameterless constructor is called 
p.FirstName = "Bob"; 
p.LastName = "Smith"; 

注意,你也可以使用一個帶參數的構造函數:

new Person(1, 2, 3) { FirstName = "Bob", LastName = "Smith" } 

被翻譯爲:

Person p = new Person(1, 2, 3); 
p.FirstName = "Bob"; 
p.LastName = "Smith"; 

關於反射:構建一個新的實例並以與我相同的方式初始化它n個new Person { FirstName = "Bob", LastName = "Smith" }例如,你必須:

  1. 檢索構造函數(見Type.GetConstructor)並調用它使用Activator.CreateInstance實例的類型,
  2. 檢索FirstName財產(見Type.GetProperty
  3. 集它(見PropertyInfo.SetValue),
  4. 重複(2)和(3)的LastName
1

你怎麼編譯這個? C#報告錯誤:

error CS0106: The modifier 'readonly' is not valid for this item 
4

這與構造函數沒有關係。 這只是簡短的語法來初始化普通屬性。

new Person { FirstName = "Bob", LastName = "smith" }; 

是完全一樣的

var person = new Person(); 
person.FirstName = "Bob"; 
person.LastName = "smith"; 

正如人們說。你的例子不會編譯。因爲它不是構造函數。

0

我猜你的意思是私有屬性setter而不是readonly屬性(get和set是整個getter和setter的簡寫)。那麼你將不得不這樣做來反射地設置屬性:

Type personType= typeof(Person); 
object personInstance = Activator.CreateInstance(personType); 
personInstance.GetProperty("FirstName").SetValue(classObject, "Bob, null); 
personInstance.GetProperty("LastName").SetValue(classObject, "smith, null); 
相關問題