2010-07-13 2 views
4

Voici ce que je veux faire ...Comment autoriser ma classe à être implicitement convertie en chaîne en C#?

public class A 
{ 
    public string Content { get; set; } 
} 

A a = new A(); 
a.Content = "Hello world!"; 
string b = a; // b now equals "<span>Hello world!</span>" 

Je veux contrôler commenta est converti en un String & hellip; en quelque sorte & hellip;

+0

Ce qui manque ici, c'est un indice sur le fait de surcharger 'ToString()'. – Oliver

+0

@Oliver: ça a été soulevé plusieurs fois, et renversé à plusieurs reprises, comme a) ce n'est pas un casting implicite, et b) c'est encore plus déroutant qu'un casting implicite. –

Répondre

8
public class A 
{ 
    public string Content { get; set; } 
    public static implicit operator string(A a) 
    { 
     return string.Format("<span>{0}</span>", a.Content); 
    } 
} 
+0

Réponse absolument parfaite! Merci beaucoup! – jedmao

+0

+1 pour une réponse complètement correcte. Cependant, je recommande vivement de ne pas le faire en pratique, pour les raisons mentionnées dans la réponse de David. –

12

Vous pouvez remplacer manuellement les opérateurs de distribution implicite et explicite d'une classe. Tutorial here. Je dirais que c'est un mauvais design la plupart du temps, cependant. Je dirais qu'il est plus facile de voir ce qui se passe si vous avez écrit

string b = a.ToHtml(); 

Mais il est certainement possible ...

public class A 
{ 
    public string Content { get; set; } 

    public static implicit operator string(A obj) 
    { 
     return string.Concat("<span>", obj.Content, "</span>"); 
    } 
} 

Pour donner un exemple de pourquoi je ne recommande pas, considérer les points suivants :

var myHtml = "<h1>" + myA + "</h1>"; 

La volonté ci-dessus, donne "<h1><span>Hello World!</span></h1>"

maintenant, un autre développeur arrive et pense que le code semble au-dessus de pauvres et reformate dans les éléments suivants:

var myHtml = string.Format("<h1>{0}</h1>", myA); 

Mais string.Format appelle en interne ToString pour tous les arguments qu'il reçoit, donc nous ne sommes plus face à un casting implicite, et par conséquent, l'autre développeur aura changé le résultat de quelque chose comme "<h1>myNamespace.A</h1>"

+0

Je suis d'accord avec vous sur la mauvaise conception; Cependant, mon exemple n'est qu'un exemple. Ce que je veux faire est beaucoup plus compliqué. Merci d'avoir répondu! C'est très utile. – jedmao

+4

@sfjedi: Plus le scénario est complexe, moins les conversions implicites sont appropriées, IMO. Il y a * très * peu d'endroits où cela rend le code plus clair, selon mon expérience. –

+0

J'irais toujours avec "ToString()" pour convertir en une chaîne, penser plus tard quand quelqu'un maintient le code et assigne accidentellement l'objet à une chaîne au lieu d'une copie de l'objet ... pourrait prendre des semaines à traquer (en raison de l'aveuglement de code) – Mauro

3
public static implicit operator string(A a) 
{ 
    return "foo"; 
} 
+0

Bonne réponse, mais je voterai la réponse de @ desco parce qu'elle est plus complète. Pardon. – jedmao

0

remplaçant ToString() serait belle façon. De plus, en mode débogage, vous avez un astuce avec la valeur de retour ToString().

+0

copie de ma réponse à BennySkogbergs maintenant supprimé réponse: Je dirais remplacer OverString est encore plus trompeuse que la distribution implicite. Lorsque vous utilisez un casting implicite, quelqu'un peut être trompé en pensant que 'a' est une chaîne, mais si vous regardez assez attentivement, vous verrez que * quelque chose * de poisson se passe. avec ce code * tout le monde * supposera que 'b' contiendra quelque chose comme" monNamespace.A "après cette opération. –