ValueTuples lose their property names when serialized












17















While trying to serialize a named value tuple to JSON string, it loses the names assigned to items



(string type, string text) myTypes = ("A", "I am an animal");
var cnvValue = JsonConvert.SerializeObject(myTypes);


I am expecting the serialized value as




{"type":"A","text":"I am an animal"}




but the actual results are




{"Item1":"A","Item2":"I am an animal"}




There are two things that i am interested to know




  • Why does it behave like that

  • How to get the expected output










share|improve this question




















  • 3





    FYI github.com/JamesNK/Newtonsoft.Json/issues/1505

    – John
    Jan 28 at 8:22
















17















While trying to serialize a named value tuple to JSON string, it loses the names assigned to items



(string type, string text) myTypes = ("A", "I am an animal");
var cnvValue = JsonConvert.SerializeObject(myTypes);


I am expecting the serialized value as




{"type":"A","text":"I am an animal"}




but the actual results are




{"Item1":"A","Item2":"I am an animal"}




There are two things that i am interested to know




  • Why does it behave like that

  • How to get the expected output










share|improve this question




















  • 3





    FYI github.com/JamesNK/Newtonsoft.Json/issues/1505

    – John
    Jan 28 at 8:22














17












17








17








While trying to serialize a named value tuple to JSON string, it loses the names assigned to items



(string type, string text) myTypes = ("A", "I am an animal");
var cnvValue = JsonConvert.SerializeObject(myTypes);


I am expecting the serialized value as




{"type":"A","text":"I am an animal"}




but the actual results are




{"Item1":"A","Item2":"I am an animal"}




There are two things that i am interested to know




  • Why does it behave like that

  • How to get the expected output










share|improve this question
















While trying to serialize a named value tuple to JSON string, it loses the names assigned to items



(string type, string text) myTypes = ("A", "I am an animal");
var cnvValue = JsonConvert.SerializeObject(myTypes);


I am expecting the serialized value as




{"type":"A","text":"I am an animal"}




but the actual results are




{"Item1":"A","Item2":"I am an animal"}




There are two things that i am interested to know




  • Why does it behave like that

  • How to get the expected output







c# json.net tuples valuetuple






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 28 at 8:47









Caius Jard

12.1k21240




12.1k21240










asked Jan 28 at 8:20









mdowesmdowes

15311




15311








  • 3





    FYI github.com/JamesNK/Newtonsoft.Json/issues/1505

    – John
    Jan 28 at 8:22














  • 3





    FYI github.com/JamesNK/Newtonsoft.Json/issues/1505

    – John
    Jan 28 at 8:22








3




3





FYI github.com/JamesNK/Newtonsoft.Json/issues/1505

– John
Jan 28 at 8:22





FYI github.com/JamesNK/Newtonsoft.Json/issues/1505

– John
Jan 28 at 8:22












3 Answers
3






active

oldest

votes


















18















How to get the expected output




Something like this:



var myTypes = new{ type = "A", text = "I am an animal"};
var cnvValue = JsonConvert.SerializeObject(myTypes);


should work if you’re looking for a similarly terse approach. Doesn’t use ValueTuples (but anonymous types) under the hood though; this is my interpreting your question as “how can I produce this expected JSON without going to the full extent of declaring a class etc”






share|improve this answer





















  • 2





    You interpreted it in the correct sense. I used ValueTuples to do exactly that.

    – mdowes
    Jan 28 at 8:57



















16














The names are a compiler trick. If you look at the definition for ValueTuple you'll see that its field names are just Item1, Item2, etc.



Since JsonConvert.SerializeObject was compiled well before you assigned names that you could use during your compilation, it cannot recover the names.



Method parameters/return types are decorated with attributes that indicate the names to be used when a method's signature includes ValueTuples. This allows code authored later to "see" the names by the compiler playing tricks again, but that's the "wrong way around" to be of much use here.




How to get the expected output




Introduce an explicit type, if the names of the fields/properties are so important.






share|improve this answer


























  • Important to note that the explicit type could be an anonymous type.

    – Avner Shahar-Kashtan
    Jan 28 at 8:30






  • 3





    @AvnerShahar-Kashtan Anonymous type are not explicit anyway

    – Rahul
    Jan 28 at 8:39











  • I do not want to create an explicit type to use it only once. But still I want the names of items to appear in JSON string.

    – mdowes
    Jan 28 at 8:55











  • If you want the better names, you need to at least use an anonymous type, or a named type. ValueTuple will not help you, as you've seen.

    – Lasse Vågsæther Karlsen
    Jan 28 at 9:02



















0















How to get the expected output




Use explicit custom type or anonymous class like in @Caius answer.



Or don't create special type for it at all (for anonymous type compiler generates class behind the scene for you) and use JObject to dynamically create json:



var myTypesJson = new JObject(
new JProperty("type", "A"),
new JProperty("text", "I am an animal")
);
var cnvValue = myTypesJson.ToString();


or use indexer and initialization syntax for it:



var createdJson = new JObject()
{
["type"] = "A",
["text"] = "I am an animal"
};
var cnvValue = createdJson.ToString();





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54397927%2fvaluetuples-lose-their-property-names-when-serialized%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    18















    How to get the expected output




    Something like this:



    var myTypes = new{ type = "A", text = "I am an animal"};
    var cnvValue = JsonConvert.SerializeObject(myTypes);


    should work if you’re looking for a similarly terse approach. Doesn’t use ValueTuples (but anonymous types) under the hood though; this is my interpreting your question as “how can I produce this expected JSON without going to the full extent of declaring a class etc”






    share|improve this answer





















    • 2





      You interpreted it in the correct sense. I used ValueTuples to do exactly that.

      – mdowes
      Jan 28 at 8:57
















    18















    How to get the expected output




    Something like this:



    var myTypes = new{ type = "A", text = "I am an animal"};
    var cnvValue = JsonConvert.SerializeObject(myTypes);


    should work if you’re looking for a similarly terse approach. Doesn’t use ValueTuples (but anonymous types) under the hood though; this is my interpreting your question as “how can I produce this expected JSON without going to the full extent of declaring a class etc”






    share|improve this answer





















    • 2





      You interpreted it in the correct sense. I used ValueTuples to do exactly that.

      – mdowes
      Jan 28 at 8:57














    18












    18








    18








    How to get the expected output




    Something like this:



    var myTypes = new{ type = "A", text = "I am an animal"};
    var cnvValue = JsonConvert.SerializeObject(myTypes);


    should work if you’re looking for a similarly terse approach. Doesn’t use ValueTuples (but anonymous types) under the hood though; this is my interpreting your question as “how can I produce this expected JSON without going to the full extent of declaring a class etc”






    share|improve this answer
















    How to get the expected output




    Something like this:



    var myTypes = new{ type = "A", text = "I am an animal"};
    var cnvValue = JsonConvert.SerializeObject(myTypes);


    should work if you’re looking for a similarly terse approach. Doesn’t use ValueTuples (but anonymous types) under the hood though; this is my interpreting your question as “how can I produce this expected JSON without going to the full extent of declaring a class etc”







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 28 at 11:44









    Mafii

    5,14212445




    5,14212445










    answered Jan 28 at 8:41









    Caius JardCaius Jard

    12.1k21240




    12.1k21240








    • 2





      You interpreted it in the correct sense. I used ValueTuples to do exactly that.

      – mdowes
      Jan 28 at 8:57














    • 2





      You interpreted it in the correct sense. I used ValueTuples to do exactly that.

      – mdowes
      Jan 28 at 8:57








    2




    2





    You interpreted it in the correct sense. I used ValueTuples to do exactly that.

    – mdowes
    Jan 28 at 8:57





    You interpreted it in the correct sense. I used ValueTuples to do exactly that.

    – mdowes
    Jan 28 at 8:57













    16














    The names are a compiler trick. If you look at the definition for ValueTuple you'll see that its field names are just Item1, Item2, etc.



    Since JsonConvert.SerializeObject was compiled well before you assigned names that you could use during your compilation, it cannot recover the names.



    Method parameters/return types are decorated with attributes that indicate the names to be used when a method's signature includes ValueTuples. This allows code authored later to "see" the names by the compiler playing tricks again, but that's the "wrong way around" to be of much use here.




    How to get the expected output




    Introduce an explicit type, if the names of the fields/properties are so important.






    share|improve this answer


























    • Important to note that the explicit type could be an anonymous type.

      – Avner Shahar-Kashtan
      Jan 28 at 8:30






    • 3





      @AvnerShahar-Kashtan Anonymous type are not explicit anyway

      – Rahul
      Jan 28 at 8:39











    • I do not want to create an explicit type to use it only once. But still I want the names of items to appear in JSON string.

      – mdowes
      Jan 28 at 8:55











    • If you want the better names, you need to at least use an anonymous type, or a named type. ValueTuple will not help you, as you've seen.

      – Lasse Vågsæther Karlsen
      Jan 28 at 9:02
















    16














    The names are a compiler trick. If you look at the definition for ValueTuple you'll see that its field names are just Item1, Item2, etc.



    Since JsonConvert.SerializeObject was compiled well before you assigned names that you could use during your compilation, it cannot recover the names.



    Method parameters/return types are decorated with attributes that indicate the names to be used when a method's signature includes ValueTuples. This allows code authored later to "see" the names by the compiler playing tricks again, but that's the "wrong way around" to be of much use here.




    How to get the expected output




    Introduce an explicit type, if the names of the fields/properties are so important.






    share|improve this answer


























    • Important to note that the explicit type could be an anonymous type.

      – Avner Shahar-Kashtan
      Jan 28 at 8:30






    • 3





      @AvnerShahar-Kashtan Anonymous type are not explicit anyway

      – Rahul
      Jan 28 at 8:39











    • I do not want to create an explicit type to use it only once. But still I want the names of items to appear in JSON string.

      – mdowes
      Jan 28 at 8:55











    • If you want the better names, you need to at least use an anonymous type, or a named type. ValueTuple will not help you, as you've seen.

      – Lasse Vågsæther Karlsen
      Jan 28 at 9:02














    16












    16








    16







    The names are a compiler trick. If you look at the definition for ValueTuple you'll see that its field names are just Item1, Item2, etc.



    Since JsonConvert.SerializeObject was compiled well before you assigned names that you could use during your compilation, it cannot recover the names.



    Method parameters/return types are decorated with attributes that indicate the names to be used when a method's signature includes ValueTuples. This allows code authored later to "see" the names by the compiler playing tricks again, but that's the "wrong way around" to be of much use here.




    How to get the expected output




    Introduce an explicit type, if the names of the fields/properties are so important.






    share|improve this answer















    The names are a compiler trick. If you look at the definition for ValueTuple you'll see that its field names are just Item1, Item2, etc.



    Since JsonConvert.SerializeObject was compiled well before you assigned names that you could use during your compilation, it cannot recover the names.



    Method parameters/return types are decorated with attributes that indicate the names to be used when a method's signature includes ValueTuples. This allows code authored later to "see" the names by the compiler playing tricks again, but that's the "wrong way around" to be of much use here.




    How to get the expected output




    Introduce an explicit type, if the names of the fields/properties are so important.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 28 at 8:37

























    answered Jan 28 at 8:23









    Damien_The_UnbelieverDamien_The_Unbeliever

    196k17253340




    196k17253340













    • Important to note that the explicit type could be an anonymous type.

      – Avner Shahar-Kashtan
      Jan 28 at 8:30






    • 3





      @AvnerShahar-Kashtan Anonymous type are not explicit anyway

      – Rahul
      Jan 28 at 8:39











    • I do not want to create an explicit type to use it only once. But still I want the names of items to appear in JSON string.

      – mdowes
      Jan 28 at 8:55











    • If you want the better names, you need to at least use an anonymous type, or a named type. ValueTuple will not help you, as you've seen.

      – Lasse Vågsæther Karlsen
      Jan 28 at 9:02



















    • Important to note that the explicit type could be an anonymous type.

      – Avner Shahar-Kashtan
      Jan 28 at 8:30






    • 3





      @AvnerShahar-Kashtan Anonymous type are not explicit anyway

      – Rahul
      Jan 28 at 8:39











    • I do not want to create an explicit type to use it only once. But still I want the names of items to appear in JSON string.

      – mdowes
      Jan 28 at 8:55











    • If you want the better names, you need to at least use an anonymous type, or a named type. ValueTuple will not help you, as you've seen.

      – Lasse Vågsæther Karlsen
      Jan 28 at 9:02

















    Important to note that the explicit type could be an anonymous type.

    – Avner Shahar-Kashtan
    Jan 28 at 8:30





    Important to note that the explicit type could be an anonymous type.

    – Avner Shahar-Kashtan
    Jan 28 at 8:30




    3




    3





    @AvnerShahar-Kashtan Anonymous type are not explicit anyway

    – Rahul
    Jan 28 at 8:39





    @AvnerShahar-Kashtan Anonymous type are not explicit anyway

    – Rahul
    Jan 28 at 8:39













    I do not want to create an explicit type to use it only once. But still I want the names of items to appear in JSON string.

    – mdowes
    Jan 28 at 8:55





    I do not want to create an explicit type to use it only once. But still I want the names of items to appear in JSON string.

    – mdowes
    Jan 28 at 8:55













    If you want the better names, you need to at least use an anonymous type, or a named type. ValueTuple will not help you, as you've seen.

    – Lasse Vågsæther Karlsen
    Jan 28 at 9:02





    If you want the better names, you need to at least use an anonymous type, or a named type. ValueTuple will not help you, as you've seen.

    – Lasse Vågsæther Karlsen
    Jan 28 at 9:02











    0















    How to get the expected output




    Use explicit custom type or anonymous class like in @Caius answer.



    Or don't create special type for it at all (for anonymous type compiler generates class behind the scene for you) and use JObject to dynamically create json:



    var myTypesJson = new JObject(
    new JProperty("type", "A"),
    new JProperty("text", "I am an animal")
    );
    var cnvValue = myTypesJson.ToString();


    or use indexer and initialization syntax for it:



    var createdJson = new JObject()
    {
    ["type"] = "A",
    ["text"] = "I am an animal"
    };
    var cnvValue = createdJson.ToString();





    share|improve this answer




























      0















      How to get the expected output




      Use explicit custom type or anonymous class like in @Caius answer.



      Or don't create special type for it at all (for anonymous type compiler generates class behind the scene for you) and use JObject to dynamically create json:



      var myTypesJson = new JObject(
      new JProperty("type", "A"),
      new JProperty("text", "I am an animal")
      );
      var cnvValue = myTypesJson.ToString();


      or use indexer and initialization syntax for it:



      var createdJson = new JObject()
      {
      ["type"] = "A",
      ["text"] = "I am an animal"
      };
      var cnvValue = createdJson.ToString();





      share|improve this answer


























        0












        0








        0








        How to get the expected output




        Use explicit custom type or anonymous class like in @Caius answer.



        Or don't create special type for it at all (for anonymous type compiler generates class behind the scene for you) and use JObject to dynamically create json:



        var myTypesJson = new JObject(
        new JProperty("type", "A"),
        new JProperty("text", "I am an animal")
        );
        var cnvValue = myTypesJson.ToString();


        or use indexer and initialization syntax for it:



        var createdJson = new JObject()
        {
        ["type"] = "A",
        ["text"] = "I am an animal"
        };
        var cnvValue = createdJson.ToString();





        share|improve this answer














        How to get the expected output




        Use explicit custom type or anonymous class like in @Caius answer.



        Or don't create special type for it at all (for anonymous type compiler generates class behind the scene for you) and use JObject to dynamically create json:



        var myTypesJson = new JObject(
        new JProperty("type", "A"),
        new JProperty("text", "I am an animal")
        );
        var cnvValue = myTypesJson.ToString();


        or use indexer and initialization syntax for it:



        var createdJson = new JObject()
        {
        ["type"] = "A",
        ["text"] = "I am an animal"
        };
        var cnvValue = createdJson.ToString();






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Feb 3 at 23:15









        Mariusz PawelskiMariusz Pawelski

        11.4k73556




        11.4k73556






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54397927%2fvaluetuples-lose-their-property-names-when-serialized%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Human spaceflight

            Can not write log (Is /dev/pts mounted?) - openpty in Ubuntu-on-Windows?

            張江高科駅