C# 从类型化对象复制的动态对象具有空值

C# 从类型化对象复制的动态对象具有空值,c#,dynamic,attributes,C#,Dynamic,Attributes,我正在开发一个通用的restApi类交互程序来处理我公司的Web服务,发现了一些奇怪的东西。。 当我使用dynamictype来实现Json启用时的灵活性时,我注意到一些属性显示为null,如果在执行显式转换时还不够奇怪,那么我得到了正确的值。 我正在使用Newtonsoft.Json和.NETFramework 4.6.2中的Json 6.0.4 你们知道为什么会发生这种事情吗 下面是一个小代码来说明我所说的,您可以看到vars d_type_2和j_type_2中的bug static vo

我正在开发一个通用的restApi类交互程序来处理我公司的Web服务,发现了一些奇怪的东西。。 当我使用dynamictype来实现Json启用时的灵活性时,我注意到一些属性显示为null,如果在执行显式转换时还不够奇怪,那么我得到了正确的值。 我正在使用Newtonsoft.Json和.NETFramework 4.6.2中的Json 6.0.4

你们知道为什么会发生这种事情吗

下面是一个小代码来说明我所说的,您可以看到vars d_type_2和j_type_2中的bug

static void Main(string[] args)
    {
        var jsonString = File.ReadAllText("Json4.txt");
        var jsonObject = JValue.Parse(jsonString);

        var JsonObject_1 = jsonObject;
        dynamic JsonObject_2 = jsonObject;


        dynamic d_type_1 = JsonObject_1.Type;
        dynamic d_type_2 = JsonObject_2.Type;

        JTokenType j_type_1 = JsonObject_1.Type;
        JTokenType j_type_2 = JsonObject_2.Type;

    }

我试过两种方法。首先,我获取了一个json对象,对其进行解析,并可以重现您的案例。在此之后,我尝试使用json数组,它正确地返回了
JsonObject_2的
array

这种行为似乎很奇怪,所以我深入研究了Newtonsoft的行为

当我们使用库知道是
JObject
类型的
JsonObject\u 1
时,它将
.type
属性值作为
对象返回。
下面是的源代码中的
类型
属性getter

但对于
dynamic
,它采取了不同的路径

在开始之前,了解执行
JValue.Parse(jsonString)
时会发生什么是很重要的。 如果
jsonString
持有一个json对象,Newtonsoft库将从“jsonString”中提取
键、值
对,并将其存储在一个私有
字典
中。这将有助于我接下来的解释

现在,使用“动态”Newtonsoft可以利用.Net中的DLR功能。当我们试图读取此类
动态
对象的任何成员属性时,
它通过JObject的
DynamicProxy
方法实现。 根据这个方法的实现,它只在我上面提到的私有字典中搜索。如果未找到属性,则返回
null
.Type
因此返回null,因为它在
字典中不可用

尝试下面的(有趣的)代码变体,看看您在
d\u type\u 1
d\u type\u 2
中得到了什么:


哇,很好的解释,事情开始有意义了!在这种情况下,我希望使用对象中的objectType,而不是私有字典中名为Type的键中的值,您认为更改或重写getter方法以获取此属性可行吗?或者是另一个更简单的解决方案来继续使用动态。一些解决方法是可以确定的,但我建议只有在没有其他方法的情况下才使用
dynamic
public override JTokenType Type => JTokenType.Object;
 static void Main(string[] args)
    {
        var jsonString = " {'key1':'value1','key2':'value2','Type':'value3'} ";
        var jsonObject = JValue.Parse(jsonString);
        var JsonObject_1 = jsonObject;
        dynamic JsonObject_2 = jsonObject;
        
        dynamic d_type_1 = JsonObject_1.Type;
        dynamic d_type_2 = JsonObject_2.Type;
    }