System.Json中的JsonValue ToString()方法与(string)转换的区别

3

我想知道在ToString()和(string)转换之间为什么会有值的差异?

许多类似的问题都指出唯一的区别应该是您无法在null值上调用ToString()。

var json = "{\"someKey\":\"Hello world!\"}";
var jsonObject = System.Json.JsonObject.Parse(json);

Assert.AreEqual("Hello world!", (string)jsonObject["someKey"]);    //ok 
Assert.AreEqual("Hello world!", jsonObject["someKey"].ToString()); //not equal, actual value is "Hello world!" (with quotes in the string)

你可以覆盖隐式/显式转换运算符(在你的情况下,我认为是显式的),以及ToString()方法。知道这一点就不应该让你再感到困惑了。 - Sinatr
4个回答

4
方法 System.Json.JsonObject.Parse 返回一个 JsonValue 对象,查看此处提供的源代码: https://github.com/dotnet/corefx/blob/master/src/System.Json/src/System/Json/JsonValue.cs
我们可以看到方法 ToString() 的实现如下:
public override string ToString()
{
    var sw = new StringWriter();
    Save(sw);
    return sw.ToString();
}

public virtual void Save(Stream stream)
{
    if (stream == null)
    {
        throw new ArgumentNullException(nameof(stream));
    }

    using (StreamWriter writer = new StreamWriter(stream, s_encoding, 1024, true))
    {
        Save(writer);
    }
}

然而,为了支持使用(string)实现转换成字符串,该类需要实现以下内容:

 public static implicit operator JsonValue(string value) => new JsonPrimitive(value);

通过查看此处提供的JsonPrimitive实现:https://github.com/dotnet/corefx/blob/master/src/System.Json/src/System/Json/JsonPrimitive.cs

我们可以看到有一个方法将字符串格式化如下:

internal string GetFormattedString()
{
    switch (JsonType)
    {
        case JsonType.String:
            if (_value is string || _value == null)
            {
                return (string)_value;
            }
            if (_value is char)
            {
                return _value.ToString();
            }
            throw new NotImplementedException(SR.Format(SR.NotImplemented_GetFormattedString, _value.GetType()));

        case JsonType.Number:
            string s = _value is float || _value is double ?
                ((IFormattable)_value).ToString("R", NumberFormatInfo.InvariantInfo) : // Use "round-trip" format
                ((IFormattable)_value).ToString("G", NumberFormatInfo.InvariantInfo);
            return s == "NaN" || s == "Infinity" || s == "-Infinity" ?
                "\"" + s + "\"" :
                s;

        default:
            throw new InvalidOperationException();
    }
}

这就是你得到不同结果的原因。

4
你的断言(Assert)失败的原因是因为 JsonValue.ToString() 方法是一个覆盖方法,返回一个基于文本的 JSON 字符串结果,而直接转换值会返回底层字符串值。
var test = new JsonPrimitive("test");
Console.WriteLine((string)test);    // test
Console.WriteLine(test.ToString()); // "test" - with quotes

3

2
根据这份文档ToString方法的作用是:

将此JSON CLR类型保存(序列化)为基于文本的JSON格式。

因此,它覆盖了Object.ToString()的行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接