JSON C# 7元组支持

4
我希望在我的JSON (Newtonsoft.Json)输出中获取我的C#7元组属性名称。 我的问题是: 当我想将我的元组转换为不支持参数名称的JSON格式时,遇到了困难。
例如,以下是我的“Test2”方法及其JSON输出:
public void Test2()
{
    var data = GetMe2("ok");
    var jsondata = JsonConvert.SerializeObject(data);//JSON output is {"Item1":5,"Item2":"ok ali"}
}

public (int MyValue, string Name) GetMe2(string name)
{
    return (5, name + " ali");
}

JSON输出是 "{"Item1":5,"Item2":"ok ali"}",但我希望得到 "{"MyValue":5,"Name":"ok ali"}";

这并不是不可能的,因为我可以在运行时获取属性名称:

foreach (var item in this.GetType().GetMethods())
{
    dynamic attribs = item.ReturnTypeCustomAttributes;
    if (attribs.CustomAttributes != null && attribs.CustomAttributes.Count > 0)
    {
        foreach (var at in attribs.CustomAttributes)
        {
            if (at is System.Reflection.CustomAttributeData)
            {
                var ng = ((System.Reflection.CustomAttributeData)at).ConstructorArguments;
                foreach (var ca in ng)
                {
                    foreach (var val in (IEnumerable<System.Reflection.CustomAttributeTypedArgument>)ca.Value)
                    {
                        var PropertyNameName = val.Value;
                        Console.WriteLine(PropertyNameName);//here is property names of C#7 tuple
                    }
                }
            }
        }
        dynamic data = attribs.CustomAttributes[0];
        var data2 = data.ConstructorArguments;
    }

}

啊,我明白这也是你的问题。一般来说,这种特定于库的问题更容易在GitHub问题跟踪器上得到解答,而不是在StackOverflow上。我们只能帮助你实现某种自定义方法或临时解决方案。 - Yeldar Kurmangaliyev
为什么在你已经发现Json.NET尚未实现某个功能并且已经有了相关的特性请求后,还要在Stack Overflow上提出问题呢? - Jon Skeet
是的,我之前看到过这个问题,谢谢。 - Ali Yousefi
希望有人能够在我的情况下更改JSON开源项目,因为我可以在运行时获取参数名称,我认为JSON组件必须更新到新版本以支持该功能。 - Ali Yousefi
2
我希望有人能在我的情况下修改JSON开源项目。你为什么不能成为那个“任何人”呢?获取源代码,进行更改并提交PR,而不是等待别人为您完成。 - David Arno
显示剩余4条评论
2个回答

2

对于这个具体情况,是不可能的。因为SerializeObject无法找出元组来自哪里,它只看到ValueTuple<int, string>

如果您要序列化带有元组属性的对象,则情况将不同,在这种情况下,SerializeObject可以使用反射查找TupleElementNames属性(即使它目前没有这样做)。


“TupleElementNames” 不是只应用于方法的返回值吗? - Paulo Morgado
2
@PauloMorgado 它也适用于属性和字段。 - svick
我在“方法”中包含了属性。我忘记提到字段了。尽管如此,它附加在元组的起源上,而不是元组本身。序列化器可以进行特殊处理,但您建议这样做吗?我不会这样做。 - Paulo Morgado
我不确定这是否是不可能的。例如,您可以向Dapper提供一个元组,它将成功返回一个填充元组的IEnumerable。我不确定为什么Newtonsoft不能做同样的事情。 - Zorthgo
@Zorthgo 这里的问题是 JSON.NET 无法读取元组字段的名称。可以推测,Dapper 依赖于字段的顺序而不是它们的名称。 - svick

1

简短的回答是元组没有属性。

元组是一组值的集合,主要用于从方法中返回多个值。

它们从未旨在模拟实体。

如果您不想为此创建类型,解决问题的唯一方法是:

public void Test2()
{
    var data = GetMe2("ok");
    var jsondata = JsonConvert.SerializeObject(new { data.MyValue, data.Name });//JSON output is {"Item1":5,"Item2":"ok ali"}
}

5
你可以序列化字段,但元组没有命名字段,只有Item1、Item2等。这些名称只是编译器的魔法。 - Panagiotis Kanavos
5
这段代码真的可以解决问题吗?原帖作者希望得到的输出是{"MyValue":5,"Name":"ok ali"} - VMAtm

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