我有一个具有以下结构的课程
public class GenericEntity<T>
where T : BaseClass
{
T Property {get; set;}
}
我有BaseClass
的几个具体实现,并使用这些具体实现来实例化GenericEntity
类型的对象
e.g。 var entity = new GenericEntity<DerivedClass>()
我通过将对象序列化为JSON(使用Newtonsoft)将此实体推送到消息传递框架中。在另一端,我从消息队列中提取该消息(JSON),并尝试使用JsonSerializerSettings GenericEntity<BaseClass>
将消息反序列化为类型TypeNameHandling.All
。但在反序列化时,它会抛出JsonSerializationException
详细信息
在JSON&#39; NewtonsoftPlayground.GenericEntity
1[[NewtonsoftPlayground.DerivedClass, NewtonsoftPlayground, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], NewtonsoftPlayground, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not compatible with 'NewtonsoftPlayground.GenericEntity
1 [[NewtonsoftPlayground.BaseClass,NewtonsoftPlayground,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]],NewtonsoftPlayground,Version = 1.0中指定的类型。 0.0,Culture = neutral,PublicKeyToken = null&#39;。
我怎样才能做到这一点?或者我不应该使用通用?如果是这样,我最终会在从队列中提取消息后到处编写类型转换,我试图避免这种情况。
答案 0 :(得分:1)
我重新创建了以下代码:
public class GenericEntity<T> where T : BaseClass
{
public T Property { get; set; }
}
public class BaseClass {
}
class Derived1 : BaseClass
{
public int Age { get; set; }
}
class Derived2 : BaseClass {
public string Name { get; set; }
}
....
static void Main()
{
Derived1 d1 = new Derived1 {Age = 23};
GenericEntity<Derived1> entity = new GenericEntity<Derived1> {Property = d1};
var data = JsonConvert.SerializeObject(entity, new JsonSerializerSettings() {
TypeNameHandling = TypeNameHandling.All
});
var baseEntity = JsonConvert.DeserializeObject(data, typeof(GenericEntity<BaseClass>));
}
反序列化数据时没有错误。请告诉我您的背景及其差异。
这显然不起作用:
BaseClass d1 = new Derived1 {Age = 23};
GenericEntity<BaseClass> entity = new GenericEntity<BaseClass> {Property = d1};
var data = JsonConvert.SerializeObject(entity, new JsonSerializerSettings() {
TypeNameHandling = TypeNameHandling.All
});
var baseEntity = JsonConvert.DeserializeObject<GenericEntity<Derived1>>(data, new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.All
});
如果你序列化一个BaseClass,它将不负责序列化专门类所有的额外细节(我的意思是,你想序列化一个BaseClass,这正是你要序列化的)。
将它们序列化为专门的实例是你的工作:也就是说,如果你得到一个BaseClass并且你知道你需要Derived1将该实例解析为Derived1然后序列化它。
答案 1 :(得分:0)
我无法找到任何直接的解决方案来实现这一目标。正如@Tamas Ionut所建议的,在反序列化时指定基类不会反序列化具体类的属性。
作为一种解决方法,我创建了一个静态方法,它基本上实例化GenericEntity<BaseClass>
并使用反射复制其中的所有属性。
public static GenericEntity<BaseClass> ConvertToBaseEntity(object model)
{
if (model.GetType().GetGenericTypeDefinition() != typeof(GenericEntity<>))
{
throw new ArgumentException(
"Model should be of type GenericEntity<T>.", "model");
}
GenericEntity<BaseClass> baseModel = new GenericEntity<BaseClass>();
foreach (var propertyInfo in model.GetType().GetProperties())
{
baseModel.GetType().GetProperty(propertyInfo.Name).SetValue(baseModel, propertyInfo.GetValue(model));
}
return baseModel;
}
我希望,这有助于某人。