2009-10-23 6 views
4

Disons que vous avez vous-même une classe comme les suivantes:Le compilateur C# effectuera-t-il plusieurs conversions implicites pour passer d'un type à un autre?

public sealed class StringToInt { 
    private string _myString; 
    private StringToInt(string value) 
    { 
     _myString = value; 
    } public static implicit operator int(StringToInt obj) 
    { 
     return Convert.ToInt32(obj._myString); 
    } 
    public static implicit operator string(StringToInt obj) 
    { 
     return obj._myString; 
    } 
    public static implicit operator StringToInt(string obj) 
    { 
     return new StringToInt(obj); 
    } 
    public static implicit operator StringToInt(int obj) 
    { 
     return new StringToInt(obj.ToString()); 
    } 
} 

Est-ce que vous alors en mesure d'écrire du code comme le suivant:

MyClass.SomeMethodThatOnlyTakesAnInt(aString); 

sans lui indiquant qu'il n'y a pas de conversion implicite de chaîne à int?

[Oui, je pourrais tester moi-même, mais je pensais que je le mettrais là-bas et voir ce que tous les gourous ont à dire]

+8

"Oui, je peux le tester moi-même mais je pensais que je mettrais là-bas et voir ce que tous les gourous ont à dire "- c'est une phrase étrange. Vous avez fait tous ces efforts pour générer cette classe, mais vous n'avez pas touché F5? –

+4

On dirait que vous devriez le tester vous-même comme vous l'avez dit et poster une réponse, mais je ne suis pas un gourou. –

+0

Je l'ai écrit dans la boîte de question SO. : D – RCIX

Répondre

1

Je suis à peu près certain que ce n'est pas possible sous C# 3.0. Les sections de the reference qui couvrent les conversions sont 6,4. A savoir, 6.4.4 "Conversions implicites définies par l'utilisateur".

Il ne parle que de conversions de S-> T (et non S> T-> U) qui couvre les cas tels que:

StringToInt _t = "foo"; 
int t = _t; 

et

int t = (StringToInt)"foo"; 

Si les deux ces cas impliquent seulement S-> T (deux fois).

Je suis assez sûr que ce n'est pas possible dans C# 3.0. Autoriser S-> T-> U nécessiterait beaucoup plus de travail à effectuer par le type de correspondance, au moins suivant l'algorithme spécifié.

0

Typos dans votre extrait:

public StringToInt(string value) 
{ 
    _myString = value; 
} 
public static implicit operator int(StringToInt obj) 
{ 
    return Convert.ToInt32(obj._myString); 
} 
public static implicit operator string(StringToInt obj) 
{ 
    return obj._myString; 
} 

Si aString est de type StringToInt, votre utilisation devrait fonctionner.

+0

Yup j'ai attrapé ceux-ci, mais je peux souligner que le but est d'obtenir une distribution implicite de chaîne à int ... – RCIX

+0

Puisque vous ne pouvez pas étendre les types intégrés, vous ne pouvez pas créer de nouvelles conversions implicites pour eux . Intuitivement, je ne m'attendrais pas à ce que le compilateur le permette. Il semblerait indéterminé quelles classes le compilateur regarderait pour déterminer une chaîne possible de conversions implicites. En outre, la lisibilité d'un tel code semble horrible, sans parler de résoudre les conflits lorsque vous transmettez une variable à une famille de méthodes qui a des surcharges pour ce type de variable ainsi que quelque chose qui peut être implicitement converti. –

1

Cela ne semble pas fonctionner. Il nécessite au moins une distribution explicite. Eh bien ...

10

Aucun C# n'appelle plus d'une conversion implicite définie par l'utilisateur. À partir de la section Spécification C# 6.4.3:

L'évaluation d'une conversion définie par l'utilisateur n'implique jamais plus d'un opérateur de conversion défini ou défini par l'utilisateur. En d'autres termes, une conversion du type S au type T n'effectuera jamais une conversion définie par l'utilisateur de S à X, puis exécutera une conversion définie par l'utilisateur de X à T.

+0

D'autre part, vous pourriez tricher en ayant des types transitoires juste pour convertir n'importe quoi en n'importe quoi. –

Questions connexes