2008-09-22 60 views
10

有沒有什麼辦法通過反射在.NET 3.5中運行時創建C#3.0匿名對象?我想在我的序列化方案中支持它們,所以我需要一種以編程方式操作它們的方法。通過在C#中反射創建匿名對象#

後編輯,以澄清使用情況

一個額外的約束是,我將運行所有它的Silverlight應用程序裏面,所以額外的運行時間是不是一種選擇,而不是知道如何在生成代碼飛會起作用。

回答

3

這裏是另一種方式,似乎更直接。

object anon = Activator.CreateInstance(existingObject.GetType()); 
1

使用反射來獲取類型,該類型使用GetConstructor,在構造函數中使用調用。

編輯:感謝Sklivvz爲指出,我回答說,不問了一個問題;)

回答實際問題:我發現生成的C#代碼,然後使用CodeDomProvider(但不CodeDOM本身 - 很糟糕),然後將其編譯並將其反映出來,這是在運行時執行「匿名」對象最簡單的方法。

+0

我認爲他的意思是:當沒有聲明類型 – Sklivvz 2008-09-22 09:49:01

+0

謝謝,這聽起來是可行的......但是,這將工作的Silverlight應用程序?不知道CodeDOM的東西是否可用。 – 2008-09-22 12:55:07

1

你可能想看看DLR。我還沒有這樣做,但DLR(動態語言)的用例聽起來很像你想要做的。

取決於你想要做的城堡框架的動態代理對象可能是一個不錯的選擇太多的東西。

+0

謝謝,聽起來很有趣。不過,我打算在Silverlight應用程序中使用它,可能對我來說是不可行的。 – 2008-09-22 12:56:40

3

是的,有。 從內存:

public static T create<T>(T t) 
{ 
    return Activator.CreateInstance<T>(); 
} 

object anon = create(existingAnonymousType); 
+0

謝謝,這看起來像唯一簡單的方法..雖然不是一件很簡單的事情。 – 2008-09-22 12:57:50

+0

回顧一下,這將簡單地與existingAnonymousType的編譯時類型相關聯,而不是它的運行時類型,因爲忽略通用參數的語法糖是編譯時工件。換句話說,如果它被定義爲對象,你將創建一個對象實例。 – Guvante 2008-10-08 11:03:32

1

您可以使用Reflection.Emit的動態生成所需的類,雖然這是非常討厭的代碼了。

如果你決定這條路線,我會建議你下載的Reflection Emit Language Addin,因爲這可以讓你看到如何使用Reflection.Emit構建現有的類,因此是學習這個框架的一個好方法。

+0

謝謝,這是可行的,但它可能不會與我相信現有的匿名類一起工作。 – 2008-09-22 12:58:25

1

你也可能想看看進入FormatterServices類:MSDN entry on FormatterServices

它包含GetSafeUninitializedObject做序列化時,將創建一個類的空實例,和其他幾個方便的方法。

回覆來自Michael的評論: 如果您沒有類型T的Type實例,您可以隨時從typeof(T)中獲取它。如果你有一個未知類型的對象,你可以在其上調用GetType()以獲得Type實例。