2011-01-02 3 views
9

Étant donné un code comme ceci:Comment autoriser la conversion implicite?

class Json 
{ 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
    } 

    Json MyAction() 
    { 
     return "{\"json\": 1}"; 
    } 
} 

Est-ce que je peux ajouter à la classe Json pour faire de cette compilation? Quelque chose pour laisser le compilateur savoir qu'il peut implicitement jeter une chaîne à un Json?

+1

J'ajouterais une méthode d'extension '.ToJson()' au lieu de surcharger l'opérateur 'implicit' puisque ce genre de conversion implicite constitue une violation des directives importantes (voir la réponse de Saeed). En particulier, il peut lancer, n'est pas sans perte et a une sémantique étrange dans les comparaisons. – CodesInChaos

+0

@CodeInChaos: Je peux le faire ne pas jeter :) Ma plus grande préoccupation ici est que l'action retourne simplement un type différent pour le différencier d'une chaîne, même si autrement, il peut agir parfaitement comme une chaîne. De cette façon, je sais quel ContentType définir sans que l'utilisateur doive faire un travail supplémentaire (il suffit de définir le type de retour de la fonction de manière appropriée). – mpen

Répondre

27

La déclaration de l'opérateur implicit en C# vous permet de spécifier:

{type to convert to} ({type to convert from} variablename) 

Voici un exemple simple:

class Json 
{ 
    private Json(string json) 
    { 
     //logic to parse string into object 
    } 

    public static implicit operator Json(string input) 
    { 
     return new Json(input); 
    } 
} 

Quelques notes:

  • d'abord, je n » t nécessairement aller cette route, puisque la plupart str dans votre application ne sont pas sémantiquement équivalents à une chaîne JSON. Le but d'un opérateur de conversion est de dire que deux types représentent toujours des informations sémantiquement équivalentes (ou suffisamment proches pour être sémantiquement équivalents pour être traités comme tels). Je vous recommande d'implémenter une méthode static Json Parse(string input) ou peut-être même une méthode static bool TryParse(string input, out Json json) sur votre classe Json. Le site d'appel, en général, devrait savoir s'il s'attend à ce que sa propre chaîne contienne Json.

  • Généralement, si ma classe offre une conversion de type implicite à partir d'un type, je trouve qu'il est préférable d'effectuer une analyse syntaxique ou une logique ctor pour ce même type private. Cela garantit qu'il n'y a qu'une seule façon pour les consommateurs de faire une chose particulière, et non deux façons (ctor et conversion) - d'où le ctor privé dans l'exemple ci-dessus. Il peut y avoir des exceptions à cela mais c'est une bonne règle générale pour moi.

  • La conversion implicite permet également des choses intéressantes avec les opérateurs de comparaison. Par exemple, maintenant que vous pouvez implicitement convertir de chaîne en json, vous pouvez également faire: if(myJson == "blah") et il effectuera la conversion, puis appellera l'opérateur == sur votre objet Json, qui fera par défaut une comparaison d'égalité de référence.

+0

Acceptera dans ~ 12 minutes. Je ne savais pas qu'il y avait un mot clé «implicite» pour ce genre de chose .. cool :) – mpen

4

Ajouter un opérateur implicit:

public static implicit operator Json(string s) 
{ 
    return new Json(s); 
} 

Le mot-clé implicite est utilisé pour déclarer un opérateur implicite de conversion de type défini par l'utilisateur. Utilisez-le pour activer les conversions implicites entre un type défini par l'utilisateur et un autre type, si la conversion est garantie pour ne pas provoquer de perte de données.

3

Vous pouvez avoir un convertisseur implicite, mais prendre soin que vous ne perdez pas de données:

En éliminant moulages inutiles, conversions implicites peuvent améliorer la lisibilité du code source. Cependant, car les conversions implicites peuvent se produire sans que le programmeur ne spécifie entre eux, il faut prendre soin d'éviter mauvaises surprises.En général, les opérateurs de conversion implicite ne devraient jamais jeter des exceptions et ne jamais perdre informations de sorte qu'ils peuvent être utilisés en toute sécurité sans connaissance du programmeur . Si un opérateur de conversion ne peut pas répondre à ces critères, il doit être marqué explicitement .

voir MSDN

Questions connexes