ProtoBuf型铸造问题

时间:2011-09-02 16:07:08

标签: class casting protobuf-net

我使用ProtoBuf来序列化使用Activator.CreateInstance在运行时创建的类。 不幸的是,Serializer.Deserialize方法给出错误“不期望类型,并且不能推断出合同:System.Object”。任何暗示如何解决这个问题。

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>
}
}

我选择在运行时从字符串创建和转换类,因为在ASP.NET应用程序中传递converterName变量参数,这样的类将大约为100.是的,我可以用100 If替换整个代码

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  
....

但如果可能的话,我想减少代码。

1 个答案:

答案 0 :(得分:3)

这是因为泛型方法推断T =对象。

此方案有一个非通用API;看看Serializer.NonGeneric。*

或者在v2中,TypeModel / RuntimeTypeModel下的所有内容(现在所有“真正的”代码都是)非泛型。

如果您这样做,我建议使用v2。在v1中,通用代码是“主要”,非通用代码使用反射通过MakeGenericMethod()来填充到通用代码中(相对昂贵)。在v2中,这是相反的:非通用代码是“主要”,泛型方法通过typeof(T)填充到非通用API中。