2010-08-24 31 views
2

如何聯合兩個或多個匿名(或可能不是匿名)類型的實例的成員,以便爲所有成員創建結果類型實例?創建匿名類型成員的聯合

僞例如:

var anon1 = new {FirstName = "Bill"}; 
var anon2 = new {Surname = "Hicks"}; 
var anon3 = anon1.Union(anon2); 

Debug.WriteLine(anon3.FirstName + " " + anon3.Surname); 

輸出是:「比爾·希克斯」

回答

5

編譯器只知道它被聲明的方法中,匿名類型,所以,不,你不能做這樣的事情。 (當然,你可以傳遞它,但是然後它會被輸入爲對象)。

可以聲明一個新的匿名類型有兩個屬性,但是這可能不是你想要的東西:

var anon3 = new { anon1.FirstName, anon2.Surname }; 

它可以模仿你想用C#4的dynamic結構是什麼,但隨後的回聯盟的價值是dynamic,而不是一個強大的類型。

編輯迴應您的評論:

這裏是如果你想利用dynamic

public static class AnonymousTypeExtension 
{ 
    public static dynamic Union(this object first, params object [] others) 
    { 
     var allObjects = new[] {first}.Concat(others); 
     var allProperties = allObjects.SelectMany(o => o.GetType().GetProperties(), 
          (o, p) => new {p.Name, Value = p.GetValue(o, null)}); 

     IDictionary<string,object> expando = new ExpandoObject(); 
     foreach(var property in allProperties.Where(p => !expando.ContainsKey(p.Name))) 
      expando.Add(property.Name,property.Value); 
     return expando; 
    } 
} 

這會讓你的示例代碼的工作,你如何執行歐盟法,用一個例子字符串連接的結果也是動態的,這不是Debug.WriteLine允許的輸入。這意味着你需要告訴編譯器先把它當作一個字符串來處理(在你的實際使用場景中並不是問題):

 var anon1 = new { FirstName = "Bill" }; 
     var anon2 = new { Surname = "Hicks" }; 
     var anon3 = anon1.Union(anon2); 
     string name = anon3.FirstName + " " + anon3.Surname; 
     Debug.WriteLine(name); 
+0

謝謝。我將調查** dynamic **的用法,因爲聯合結果不一定是強類型。 – ProfK 2010-08-24 17:29:08

+0

美麗的'動態'的教訓,非常感謝你。 – ProfK 2010-08-24 22:01:43

+0

這是一個很棒的例子 – klumsy 2013-06-20 00:35:43