The value of method argument changes after the met

2020-07-22 16:52发布

问题:

Perhaps I'm too tired and I'm hallucinating or maybe there's actually something wrong with C# + Mono!!

I was testing and debugging in Json.Net while I came across SetPropertyValue method of class JsonSerializerInternalReader. This method calls another private method named CalculatePropertyDetails. One of the arguments passed to CalculatePropertyDetails is called reader of type JsonReader. This object has got value before it is passed to the CalculatePropertyDetails method and it's null afterwards!!

I know it sounds so stupid and believe me I'm not naive, but what could have happened in order to see such strange behavior? Can anyone come up with a rational explanation? All I know is that this project is not multi-threaded and the results are reproducible.

The only proof I've got is the two entries on top of my call stack:

Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CalculatePropertyDetails (property={Id}, propertyConverter={JsonRpcTest.ObjectIdConverter}, containerContract={Newtonsoft.Json.Serialization.JsonObjectContract}, containerProperty=(null), reader=(null), target=(null), useExistingValue=false, currentValue=(null), propertyContract=(null), gottenCurrentValue=false) in Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:792
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue (property={Id}, propertyConverter={JsonRpcTest.ObjectIdConverter}, containerContract={Newtonsoft.Json.Serialization.JsonObjectContract}, containerProperty=(null), reader={Newtonsoft.Json.JsonTextReader}, target={JsonRpcTest.E}) in Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:750

Look for reader argument.

I'm using Ubuntu 12.04, Mono 3.2.3 and Monodevelop 4.1.7 and project is developed using Mono / .Net 4.5.

[UPDATE]

Here's a part of code from where SetPropertyValue is defined and where CalculatePropertyDetails is called:

private bool SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target)
{
    object currentValue;
    bool useExistingValue;
    JsonContract propertyContract;
    bool gottenCurrentValue;

    if (CalculatePropertyDetails(property, ref propertyConverter, containerContract, containerProperty, reader, target, out useExistingValue, out currentValue, out propertyContract, out gottenCurrentValue))
        return false;

回答1:

May be GC collects your object while execution? I saw such behaviour in one of the mono forks. You can check it - simple create the public field with reader object in the parent class for SetPropertyValue and set it with actual reader. In case of GC issue it should not be nulled after this.



标签: c# mono