C# 使用Json.NET反序列化到DynamicObject

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

如果我想使用Json.NET反序列化到
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;
    }
}