2010-09-18 82 views
80

在C#3.0,你可以創建匿名類的語法如下如何動態創建新的匿名類?

var o1 = new { Id = 1, Name = "Foo" }; 

有沒有一種方法來動態創建這些匿名類的變量?


例子:

var o1 = new { Id = 1, Name = "Foo" }; 
var o2 = new { SQ = 2, Birth = DateTime.Now }; 

動態創建實例:

var o1 = DynamicNewAnonymous(new NameValuePair("Id", 1), new NameValuePair("Name", "Foo")); 
var o2 = DynamicNewAnonymous(new NameValuePair("SQ", 2), new NameValuePair("Birth", 
DateTime.Now)); 

怎麼一回事,因爲我需要做的:

dynamic o1 = new ExpandObject(); 
o1."ID" = 1; <--"ID" is dynamic name 
o1."Name" = "Foo"; <--"Name" is dynamic name 

而且場景1:

void ShowPropertiesValue(object o) 
{ 
    Type oType = o.GetType(); 
    foreach(var pi in oType.GetProperties()) 
    { 
    Console.WriteLine("{0}={1}", pi.Name, pi.GetValue(o, null)); 
    } 
} 

如果我叫:

dynamic o1 = new ExpandObject(); 
o1.Name = "123"; 
ShowPropertiesValue(o1); 

它不能顯示結果:

Name = 123 

同時,我如何將ExpandoObject轉換爲AnonymouseType?

Type type = o1.GetType(); 
type.GetProperties(); <--I hope it can get all property of o1 

最後,我修改ShowPropertiesValue()方法

void ShowPropertiesValue(object o) 
{ 
    if(o is static object) <--How to check it is dynamic or static object? 
    { 
    Type oType = o.GetType(); 
    foreach(var pi in oType.GetProperties()) 
    { 
     Console.WriteLine("{0}={1}", pi.Name, pi.GetValue(o, null)); 
    } 
    } 
    else if(o is dynamic object) <--How to check it is dynamic or static object? 
    { 
    foreach(var pi in ???) <--How to get common dynamic object's properties info ? 
    { 
     Console.WriteLine("{0}={1}", pi.Name, pi.GetValue(o, null)); 
    } 
    } 
} 

如何實現DynamicNewAnonymous方法或如何修改ShowPropertiesValue()?

我的動機是:

dynamic o1 = new MyDynamic(); 
o1.Name = "abc"; 
Type o1Type = o1.GetType(); 
var props = o1Type.GetProperties(); <--I hope can get the Name Property 

如果我能勾dynamicObject的GetType方法的,並迫使轉換爲強類型的類型。 以上無縫代碼可以正常工作。

+0

@Vlad:我承認我對動機有點不清楚。 – 2010-09-18 01:55:29

+0

@VladLazarenko我認爲你是對的:-) – oberfreak 2011-12-01 19:02:28

+0

請告訴我們,你想做什麼以及爲什麼這是你選擇的解決方案。 – oberfreak 2011-12-01 19:03:20

回答

61

匿名類型只是隱式聲明的常規類型。它們與dynamic沒有多大關係。

現在,如果您要使用ExpandoObject並通過dynamic變量引用它,您可以隨時添加或刪除字段。

編輯

當然,你可以:只需將其轉換爲IDictionary<string, object>。然後你可以使用索引器。

可以使用相同的鑄造技術來遍歷字段:

dynamic employee = new ExpandoObject(); 
employee.Name = "John Smith"; 
employee.Age = 33; 

foreach (var property in (IDictionary<string, object>)employee) 
{ 
    Console.WriteLine(property.Key + ": " + property.Value); 
} 
// This code example produces the following output: 
// Name: John Smith 
// Age: 33 

上面的代碼,更可以通過點擊該鏈接上找到。

+1

但是ExpandoObject不能這樣做:'dynamic o1 = new ExpandObject(); o1。「ID」= 1; o1。「Name」=「Foo」;' – Flash 2010-09-18 01:57:09

+0

但它也不能這樣做:Type o1Type = o1.GetType(); var props = o1Type.GetProperties();道具爲空 – Flash 2010-09-18 02:21:28

+1

您所做的只是說動態屬性與強類型屬性不相同。這非常正確。 – 2010-09-18 02:31:09

5

您可以創建這樣一個ExpandoObject:

IDictionary<string,object> expando = new ExpandoObject(); 
expando["Name"] = value; 

它強制轉換爲動態後,這些值會像屬性:

dynamic d = expando; 
Console.WriteLine(d.Name); 

然而,它們不是實際屬性,不能使用反射訪問。所以下面的語句將返回一個null:

d.GetType().GetProperty("Name")