2011-09-02 121 views
1

我使用ProtoBuf序列化在運行時使用Activator.CreateInstance創建的類。 不幸的是,Serializer.Deserialize方法給出錯誤「類型不是預期的,並且不能推斷出合同:System.Object」。任何提示如何解決這個問題。ProtoBuf類型投射問題

var converterName = "Passing class name as string" 
var type = Type.GetType(converterName); 
      var yourObject = Activator.CreateInstance(type) 
      if (yourObject != null) 
      { 

       FillRequest(Request.Params, yourObject); 
       var com = new CommunicationLayer(); 
       yourObject = com.Submit(yourObject); 
       FillResponse(yourObject); 
      } 

public class CommunicationLayer 
{ 
public T Submit<T>(T engine) 
{ 
<code skip> 
Serializer.Serialize(stream, engine); //Works fine 
<code skip> 

    engine = Serializer.Deserialize<T>(stream); //Gives error 

<code skip> 
} 
} 

我選擇通過串運行時創建和鑄造類,因爲converterName變量參數在ASP.NET應用程序通過,這樣的班會約100是的,我可以取代100如果的

整個代碼
If converterName=="MyClass1" 
{ 
var yourObject = new MyClass1(); 
FillRequest(Request.Params, yourObject); 
       var com = new CommunicationLayer(); 
       yourObject = com.Submit(yourObject); 
       FillResponse(yourObject); 
} 
    Else 
If converterName=="MyClass2" 
{ 
var yourObject = new MyClass2(); 
FillRequest(Request.Params, yourObject); 
       var com = new CommunicationLayer(); 
       yourObject = com.Submit(yourObject); 
       FillResponse(yourObject); 
} 
    Else 
.... 

但我希望儘可能少用代碼。

回答

3

這是因爲通用方法是推斷T = object。

有一種非通用API用於此場景;看Serializer.NonGeneric。*

或者在v2中,下TypeModel/RuntimeTypeModel(其中現在所有的「真實」的代碼),一切都是整個非通用。

如果你正在做這件事,我推薦使用v2。在v1中,通用代碼是「主要」代碼,非泛型代碼使用反射通過MakeGenericMethod()(相對昂貴)填充到通用代碼中。在v2中,這是相反的:非泛型代碼是「主要」代碼,泛型方法通過typeof(T)墊入非泛型API。

+0

使用Serializer.NonGeneric類有什麼缺點嗎? – Tomas

+0

@Tomas無論如何;在* regular *代碼中,它有點不太方便(因爲您可能需要給某些方法一個'Type'實例和一個cast或兩個等),但是對於您正在做的事情 - 它是預期的API。 –