web-dev-qa-db-fra.com

Les ValueTuples perdent leurs noms de propriété lorsqu'ils sont sérialisés

Lors de la tentative de sérialisation d'un Tuple de valeur nommée en chaîne JSON, il perd les noms attribués aux éléments

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

J'attends la valeur sérialisée comme

{"type": "A", "text": "Je suis un animal"}

mais les résultats réels sont

{"Item1": "A", "Item2": "Je suis un animal"}

Il y a deux choses que je suis intéressé de savoir

  • Pourquoi ça se comporte comme ça
  • Comment obtenir la sortie attendue
22
mdowes

Comment obtenir la sortie attendue

Quelque chose comme ça:

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

devrait fonctionner si vous recherchez une approche similaire et concise. N'utilise pas ValueTuples (mais des types anonymes) sous le capot cependant; c'est mon interprétation de votre question comme "comment puis-je produire ce JSON attendu sans aller jusqu'à déclarer complètement une classe, etc."

18
Caius Jard

Les noms sont une astuce du compilateur. Si vous regardez la définition de ValueTuple vous verrez que ses noms de champs sont juste Item1, Item2, etc.

Puisque JsonConvert.SerializeObject a été compilé bien avant que vous n'attribuiez des noms que vous pourriez utiliser pendant votre compilation, il ne peut pas récupérer les noms.

Les paramètres de méthode/types de retour sont décorés avec attributs qui indiquent les noms à utiliser lorsque la signature d'une méthode inclut ValueTuples. Cela permet au code créé plus tard de "voir" les noms par le compilateur en jouant à nouveau des tours, mais c'est la "mauvaise façon" d'être utile ici.

Comment obtenir la sortie attendue

Introduisez un type explicite, si les noms des champs/propriétés sont si importants.

15

Comment obtenir la sortie attendue

Utilisez un type personnalisé explicite ou une classe anonyme comme dans la réponse @Caius.

Ou ne créez pas de type spécial pour cela (car le compilateur de type anonyme génère une classe derrière la scène pour vous) et utilisez JObject pour créer dynamiquement json:

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

ou utilisez l'indexeur et l'initialisation syntaxe pour cela:

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