C# 使用Json.NET反序列化到DynamicObject
如果我想使用Json.NET反序列化到C# 使用Json.NET反序列化到DynamicObject,c#,json.net,C#,Json.net,如果我想使用Json.NET反序列化到ExpandoObject,我可以执行以下操作: var obj2 = JsonConvert.DeserializeObject<ExpandoObject>(serializedData, new ExpandoObjectConverter()); 但当我执行以下操作时,我会得到一个错误: var obj = new SomeClass { InterfaceMember = "xyz
ExpandoObject
,我可以执行以下操作:
var obj2 = JsonConvert.DeserializeObject<ExpandoObject>(serializedData, new ExpandoObjectConverter());
但当我执行以下操作时,我会得到一个错误:
var obj = new SomeClass
{
InterfaceMember = "xyz",
X = 3
};
string serializedData = JsonConvert.SerializeObject(obj);
SomeClass2 obj2 = JsonConvert.DeserializeObject<SomeClass2>(serializedData, new ExpandoObjectConverter());
var obj=new SomeClass
{
InterfaceMember=“xyz”,
X=3
};
string serializedData=JsonConvert.SerializeObject(obj);
SomeClass2 obj2=JsonConvert.DeserializeObject(serializedData,新的ExpandObjectConverter());
错误是:
“SomeClass2”不包含“X”的定义
如何使其适用于动态对象
注意:我在这里提供具体的类
SomeClass
,只是为了示例。在运行时,它实际上可以是实现isomoInterface
的任何类型。因此,我无法直接反序列化到SomeClass
。我的实际目标是反序列化到ISomeInterface
以下SomeClass2
代码解决了这个问题(感谢@Selvin的注释和示例fiddle):
public类SomeClass2:DynamicObject,接口
{
私有字典=新字典();
[JsonProperty]
公共字符串接口成员{get;set;}
公共重写bool TryGetMember(GetMemberBinder绑定器,输出对象结果)
{
返回dictionary.TryGetValue(binder.Name,out结果);
}
public override bool TrySetMember(SetMemberBinder绑定器,对象值)
{
字典[binder.Name]=值;
返回true;
}
公共重写IEnumerable GetDynamicMemberNames()
{
返回字典。键;
}
}
我刚刚添加了
GetDynamicMemberNames
override,并将[JsonProperty]
属性添加到InterfaceMember
属性中,以便重新序列化反序列化的动态对象不会为空。下面的SomeClass2
代码解决了这个问题(感谢@Selvin的注释和示例fiddle):
public类SomeClass2:DynamicObject,接口
{
私有字典=新字典();
[JsonProperty]
公共字符串接口成员{get;set;}
公共重写bool TryGetMember(GetMemberBinder绑定器,输出对象结果)
{
返回dictionary.TryGetValue(binder.Name,out结果);
}
public override bool TrySetMember(SetMemberBinder绑定器,对象值)
{
字典[binder.Name]=值;
返回true;
}
公共重写IEnumerable GetDynamicMemberNames()
{
返回字典。键;
}
}
我刚刚添加了
GetDynamicMemberNames
覆盖并添加了[JsonProperty]
属性设置为InterfaceMember
属性,以便重新序列化反序列化的动态对象不会为空。序列化为实现特定接口的任意类型仍然不要求使用DynamicObject
。您只需在运行时使用接受类型
的重载(提供实际类型,然后转换到接口
)。。。如果您要覆盖它(TryGet/TrySet),那么这也会起作用,因为某些class2在编译时没有X的定义。。。所以显然,对于类型为SomeClass2
的变量,询问属性X是无效的。。。但是对于动态
来说valid@Selvin我尝试了你的解决方案,它可以用来创建这个动态对象。但当我再次序列化它时,它会创建一个空对象:Console.WriteLine(JsonConvert.SerializeObject(t));序列化为实现特定接口的任意类型仍然不要求使用DynamicObject
。您只需在运行时使用接受类型
的重载(提供实际类型,然后转换到接口
)。。。如果您要覆盖它(TryGet/TrySet),那么这也会起作用,因为某些class2在编译时没有X的定义。。。所以显然,对于类型为SomeClass2
的变量,询问属性X是无效的。。。但是对于动态
来说valid@Selvin我尝试了你的解决方案,它可以用来创建这个动态对象。但当我再次序列化它时,它会创建一个空对象:Console.WriteLine(JsonConvert.SerializeObject(t));
var obj = new SomeClass
{
InterfaceMember = "xyz",
X = 3
};
string serializedData = JsonConvert.SerializeObject(obj);
SomeClass2 obj2 = JsonConvert.DeserializeObject<SomeClass2>(serializedData, new ExpandoObjectConverter());
public class SomeClass2 : DynamicObject, ISomeInterface
{
private Dictionary<string, object> dictionary = new Dictionary<string, object>();
[JsonProperty]
public string InterfaceMember { get; set; }
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return dictionary.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
dictionary[binder.Name] = value;
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return dictionary.Keys;
}
}