2010-05-11 125 views
2

有沒有辦法在不同類型的不同組件之間進行強制轉換?我需要執行一個函數,它的程序集已經加載了Assembly.Load(ReadAllBytes(...)),但是它在參數投射中失敗了。那麼,有沒有什麼辦法可以在c#中「reinterpret_cast」對象?強制鑄造一種組裝類型到另一種組裝類型在c#

編輯我鑄鋼問題的

最基本的例子是:

Assembly ass = Assembly.Load(File.ReadAllBytes("external.dll")) 
object other_type_instance = ass.GetType("OtherType").InvokeMember(null, BindingFlags.CreateInstance, null, null, new Object[]{}); 
OtherType casted_isntance = (OtherType)other_type_instance; // fails with runtime error, because there are two OtherType:s classes loaded. 
+0

請提供一些代碼 – 2010-05-11 21:12:35

+0

我認爲你會更樂意編寫一個適配器類來包裝一種類型並提供與另一種類型兼容的接口。當然,如果其他類型是密封的或其他不可變的,那麼你很大程度上沒有運氣。 – 2010-12-10 19:49:19

回答

5

除非兩種類型共享繼承關係,一個通用的接口,或類型之一提供了一個轉換操作符到另一個...不。

如果您需要更具體的建議,您將不得不提供一些額外的詳細信息,但這裏是C#中鑄造行爲的一般概要。

在C#鑄造可以是表示保留操作或表示改變之一。當您將實例強制轉換爲更寬或更窄的類型時,它將繼承heirarchy或其實現的接口,您將執行保留轉換的表示。您仍然在處理相同的位,編譯器/運行時只需確保您指定的類型對於正在處理的對象的實例有效。跨繼承heirarchies或未實現實例的接口是非法的。

對於自定義類型,表示變化轉換是從現有類型創建新實例的轉換。您可以定義自己的類型轉換操作符的類型:

public class MyType 
{ 
    public static int implicit operator int(MyType t) 
    { 
     return 42; // trivial conversion example 
    } 
} 

Conversion operators可以被定義爲implicitexplicit - 它決定了編譯器是否會選擇申請他們爲你(隱含的)或將rquire你明確地投當你想要一個收斂(明確)的類型。

鑑於您所描述的內容,您可能需要編寫一個實用類來執行從一種類型到另一種類型的轉換。不幸的是,C#或.NET中沒有任何內容可以爲您做到這一點。

+0

我不認爲這是OP的要求。這個問題有點神祕,但我的理解是,由於重新加載了一個Assembly,他有兩個不同的類型標記用於加載相同的類。這會導致有趣的異常,如'someValue'(Intellisense顯示的類型爲OtherType)'不是OtherType'類型。這種情況下的「轉換」實際上更類似於馬沙林。 – 2010-05-11 22:31:25

2

如果您有兩個不同版本的程序集加載並且兩個類是兼容的(相同版本的程序集或對特定類沒有更改),則一種選擇是從一個實例序列化到內存並反序列化爲實例在你需要的裝配中。如果由於新程序集中的更改而導致類之間可能存在差異,則需要考慮更多常見的序列化問題。如果是這樣的話,我建議看看DataContractSerializer,它可以支持更復雜的場景。

+1

http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx可能會有所幫助。 – user7116 2010-05-12 00:33:05

0

最後通過使用DynamicMethod,Emit-namespace和MethodUtil.ReplaceMethod(從http://www.codeproject.com/KB/dotnet/CLRMethodInjection.aspx)的組合,在不兼容的類型之間進行投射。很難說哪些是必要的,如果你有興趣只在鑄造這是可選的...我只是很高興外部功能invokation工作,即使它的參數是從不同的組件......

+1

有趣,但也非常可怕。 – 2010-05-12 23:26:43

0

C#許可證不確定的輸入,比如var和object,但這兩者在行爲上是完全不同的。例如,假設您已經序列化了一個類或結構體,並且不能將其強制轉換爲在Array.Copy方法中使用。一種解決方法是返回到您的類或結構實例化,並將其轉換爲「對象」。這樣編譯器將允許你在必要時將它投射到任何地方。

當然,您將失去該類型安全性的保護,但對於小部分代碼而言,與編寫整個鑄造方法相比,這將是更易於管理的解決方案。