10
votes

C #: Casting personnalisé à un type de valeur

est-il possible de lancer une classe personnalisée à un type de valeur?

Voici un exemple: P>

var x = new Foo();
var y = (int) x; //Does not compile 


1 commentaires

Que pensez-vous que cela fasse? I.o.w, qu'est-ce que foo ressemble?


5 Réponses :


23
votes

Vous devrez surcharger l'opérateur de distribution.

    public class Foo
    {
        public Foo( double d )
        {
            this.X = d;
        }

        public double X
        {
            get;
            private set;
        }


        public static implicit operator Foo( double d )
        {
            return new Foo (d);
        }

        public static explicit operator double( Foo f )
        {
            return f.X;
        }

    }


2 commentaires

Pouvez-vous s'il vous plaît expliquer l'utilisation de votre réponse implicite et explicite? Merci.


Excellent, exactement ce que j'étais recherché dans la réponse. À votre santé.



7
votes

Créer une conversion explicite ou implicite: xxx pré>

La différence est, avec des conversions explicites, vous devrez faire le type vous-même: P>

double d = new Foo();


0 commentaires

0
votes

Une autre possibilité est d'écrire une méthode d'extension d'analyse et de tryparse pour votre classe.

Vous écrivez ensuite votre code comme suit: p>

var x = new Foo();
var y = int.Parse(x); 


6 commentaires

Pourquoi l'écririez-vous comme une méthode d'extension et non comme une méthode de membre régulier? C'est sa classe, alors il contrôle dessus.


Parce que lorsque vous avez un marteau, chaque problème est un clou.


@Mark: Même si vous avez écrit une méthode d'extension, vous ne pouvez pas l'utiliser avec "var y = int.parse (x);" Parce que les méthodes d'extension ne s'appliquent qu'aux instances. Vous devriez faire quelque chose comme "var y = x.parsetoint ();" Au lieu de cela, et dans ce cas pourquoi ne pas simplement mettre la méthode PaSTSoint dans la classe elle-même, comme le dit Frederik.


Sans en savoir plus sur sa classe FOO, j'ai simplement offert une autre possibilité. @Martin Brown: suggérez-vous que les autres méthodes tryyarse sont des marteaux? Non, ils correspondent à leur paradigme de traiter des chaînes. Je ne peux pas vraiment déduire une grande partie du domaine problématique. @Fredererik: Il a tout autant de contrôle avec une méthode d'extension qu'il le fait avec sa propre classe.


Aucune marque, Martin suggère que les méthodes d'extension sont des marteaux. :) Le problème avec une méthode d'extension, c'est que vous diffusez la logique de diffusion partout et que la méthode d'extension ne sera pas affichée directement par IntelliSense, si l'espace de noms où la méthode d'extension est définie, n'est pas "utilisé". Puisque vous avez le contrôle de la classe FOO, il est préférable d'écrire la méthode Tryparse comme une méthode de membre régulier, au lieu d'une méthode d'extension.


@Mark: En Angleterre, le marteau est un dicton qui a peut-être un peu plus de sens que les mots convaincre. Voir EN.Wikipedia.org/wiki/golden_hammer . J'essayais d'impliquer que les gens en général (pas seulement) (pas seulement vous), prenez l'habitude de suggérer des méthodes d'extension et de Linq, car ils sont la dernière chose cool et non parce qu'ils sont le meilleur outil pour le travail. Dans ce cas, ce n'est pas le meilleur outil à cause de toutes les raisons de Frederik viennent de donner.



5
votes

Vous devez définir explicite ou Implicit Casting:

public class Foo
{
    public static implicit operator int(Foo d)
    {
        return d.SomeIntProperty;
    }

    // ...


0 commentaires

1
votes

Je vous suggérerais de mettre en œuvre l'interface iconvertible comme celle-ci est conçue pour gérer cela. Voir http://msdn.microsoft.com/en-us/library /ystem.iconvertible.aspx


0 commentaires