开发者

ProtoBuf type casting problem

开发者 https://www.devze.com 2023-04-02 16:23 出处:网络
I use ProtoBuf to serialize class which is create开发者_运维技巧d at runtime using Activator.CreateInstance.

I use ProtoBuf to serialize class which is create开发者_运维技巧d at runtime using Activator.CreateInstance. Unfortunately Serializer.Deserialize method gives error "Type is not expected, and no contract can be inferred: System.Object". Any hint how to solve this.

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

I have choose to create and cast class at runtime from string because converterName variable parameter is passed in ASP.NET app and such classes will be about 100. Yes, I could replace the whole code with 100 If's

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

but I would like to have less code if possible.


That is because the generic method is inferring T=object.

There is a non-generic API intended for this scenario; look at Serializer.NonGeneric.*

Or in v2, everything under TypeModel/RuntimeTypeModel (where all the "real" code now is) is also non-generic throughout.

If you are doing this lots, I recommend using v2. In v1 the generic code is the "primary", with the non-generic code using reflection to shim into the generic code via MakeGenericMethod() (relatively expensive). In v2 this is reversed: the non-generic code is the "primary", and the generic methods shim into the non-generic API via typeof(T).

0

精彩评论

暂无评论...
验证码 换一张
取 消