2017-01-06 2 views
0

J'ai une structure de classe qui a peu de propriétés de chaîne, et je veux ajouter une autre propriété qui renvoie la valeur de chaîne Json le même objet dynamiquement.Comment éviter d'appeler une propriété pour la deuxième fois, tout en utilisant le même objet avec la clause "this"

Mon problème est, quand je l'utilise this tout en créant le résultat Json, il appelle à nouveau l'objet récursive et accidents avec StackOverflowException à la fin.

J'ai essayé de changer le champ this avec New Introducer() { Id = this.Id } mais cela a provoqué la même erreur.

Bien que je sois capable de le résoudre en identifiant un paramètre booléen IsSerializing et en contournant manuellement le champ pour la deuxième fois, je cherche une solution plus décente.

Existe-t-il une commande ou un attribut pour empêcher le compilateur d'appeler la propriété Serialized pour la deuxième fois? Ou est-ce que j'appelle la propriété d'une mauvaise façon en premier lieu?

Voici ma classe:

public class Introducer 
{ 
    public Introducer() 
    { 
     this.Id = 0; 
     this.NameSurname = string.Empty; 
     this.EmailAddress = string.Empty; 
     this.UserCreated = new User(); 
    } 

    public int Id { get; set; } 
    private string _NameSurname; 
    public string NameSurname { get { return _NameSurname; } set { _NameSurname = value.Trim(); } } 
    private string _EmailAddress; 
    public string EmailAddress { get { return _EmailAddress; } set { _EmailAddress = value.Trim(); } } 
    public DateTime DateCreated { get; set; } 
    public User UserCreated { get; set; } 

    public string Serialized 
    { 
     get 
     { 
      return JsonConvert.SerializeObject(this, Formatting.Indented); 
     } 
    } 
} 
+1

Peut-être, ne déclarez pas la propriété sérialisée comme publique, juste interne. – Graffito

+0

[Comment exclure une propriété de Json Serialization] (http://stackoverflow.com/q/10169648/669576) –

+2

Vous pouvez ajouter un attribut '[JsonIgnore]' à cette propriété. Ou en faire une méthode. – stuartd

Répondre

1

Voici un échantillon d'essayer. L'idée est d'utiliser l'attribut JsonIgnore pour indiquer au sérialiseur de ne pas récupérer la propriété pour la sérialisation.

class MyClass 
{ 
    public int Id { get; set; } 
    private string _NameSurname; 
    public string NameSurname { get { return _NameSurname; } set { _NameSurname = value.Trim(); } } 
    private string _EmailAddress; 
    public string EmailAddress { get { return _EmailAddress; } set { _EmailAddress = value.Trim(); } } 
    public DateTime DateCreated { get; set; } 

    [JsonIgnore] 
    public string Serialized 
    { 
     get 
     { 
      return JsonConvert.SerializeObject(this, Formatting.Indented); 
     } 
    } 
} 

invoquez comme:

MyClass obj = new MyClass(); 
var serialized = obj.Serialized; 

EDIT:

Bonne pratique 1: Comme mentionné dans d'autres réponses, un method pourrait être utilisé au lieu du property comme ci-dessous:

class MyClass 
{ 
    public int Id { get; set; } 
    private string _NameSurname; 
    public string NameSurname { get { return _NameSurname; } set { _NameSurname = value.Trim(); } } 
    private string _EmailAddress; 
    public string EmailAddress { get { return _EmailAddress; } set { _EmailAddress = value.Trim(); } } 
    public DateTime DateCreated { get; set; } 

    public string GetJSON() 
    { 
     return JsonConvert.SerializeObject(this, Formatting.Indented); 
    } 
} 

Bonne pratique 2: Suivez les bons modèles OOD et laissez la sérialisation (ou la représentation) de l'objet dans un format distinct dans class.

+0

Merci pour la réponse détaillée, j'ai réussi à mettre en œuvre la bonne solution avec "JSonIgnore". Vous avez probablement raison sur la "bonne pratique", mais j'aime bien la "version sérialisée" d'une certaine façon, cela me donne le sentiment d'une "propriété générale" dans mon code. –

1

Utilisez [JsonIgnore] Ou mieux encore, changer cela en une méthode

2

Vous ne devriez pas mettre du code comme ça dans une propriété. Les propriétés sont prévues (conceptuellement) pour les données et seulement une complexité insignifiante du code; certainement pas de code récursif. La sérialisation n'est certainement pas un code insignifiant. Si souhaitait avoir une propriété Serialized qui était conceptuellement appropriée, elle devrait contenir une version mise en cache de l'objet sérialisé plutôt que de générer réellement les données sérialisées. Au lieu de cela, la fonctionnalité de génération de la représentation sérialisée de l'objet doit être dans une méthode, pas une propriété.

+0

Je seconde @BlueMonkMN. La fonction d'extension ou la substitution ToString() sont des options pour y parvenir. –