Проблема приведения типа ProtoBuf - PullRequest
1 голос
/ 02 сентября 2011

Я использую 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 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 Ответ

3 голосов
/ 02 сентября 2011

Это потому, что универсальный метод выводит T = object.

Для этого сценария предусмотрен неуниверсальный API;посмотрите на Serializer.NonGeneric. *

Или в v2, все в TypeModel / RuntimeTypeModel (где сейчас находится весь «настоящий» код) и не является универсальным во всем.

Если вы делаете это много, я рекомендую использовать v2.В v1 универсальный код является «первичным», а неуниверсальный код использует отражение для вставки в универсальный код через MakeGenericMethod() (относительно дорого).В v2 все наоборот: неуниверсальный код является «основным», а универсальные методы переходят в неуниверсальный API через typeof(T).

...