9
votes

Y a-t-il un moyen «bon marché et facile» de savoir si un objet implémente un opérateur de distribution explicite / implicite à un type particulier?

Ceci est mieux illustré avec un exemple: xxx pré>

Je veux dire, pour un objet arbitraire, si je peux le jeter à Cat. Malheureusement, je ne peux pas sembler utiliser l'opérateur IS / en tant qu'opérateur. P>

void Main()
{
    var d = new Dog();
    if (d is Cat) throw new Exception("d is Cat");
    var c1 = (Cat)d; // yes
    //var c2 = d as Cat; // Won't compile: Cannot convert type 'Dog' to 'Cat' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

}


1 commentaires

J'espère qu'aucun animal n'a été blessé d'écrire cette question.


3 Réponses :


7
votes

Les opérateurs de conversion ne sont pas vérifiés par IS / AS. Vous auriez besoin d'utiliser une réflexion à la fois pour vérifier et invoquer, ces opérateurs. J'écrirais une classe statique générique

public static TTo Convert(TFrom obj) { return del(obj); }
public static bool CanConvert { get { return del != null; } }
private static readonly Func<TFrom,TTo> del;


1 commentaires

De la mémoire, op_implicite, etc. - mais je suis sur iPod, alors je ne peux pas vérifier :)



4
votes

Malheureusement, même try / attrape ne vous aidera pas dans ce scénario pour des objets arbitraires tels que System.Object et Interfaces. Le compilateur C # considère que les conversions définies par les utilisateurs s'ils sont visibles au point de la compilation. Par conséquent, pour system.Object et interfaces qu'ils ne sont pas pris en compte.

Toutefois, dans le code exemple ci-dessus, vous ne traitez que des types de béton. Classe et struct types (non interfaces ou system.Object). Si votre scénario inclut uniquement des types de béton, le moyen le plus simple de vérifier est de faire la distribution. Le compilateur sera une erreur s'il n'y a pas de conversion disponible entre 2 types de béton xxx


1 commentaires

Essayez / Catch ne fonctionnera pas, car si le compilateur ne peut pas trouver de convertir, il suppose que vous voulez dire un casting de référence



2
votes

Les opérateurs de conversion en C # sont conçus pour être utilisés à la compilation, de sorte que le compilateur les invoque à l'époque où il est logique. Le type de test que vous souhaitez est un test d'exécution, et vous serez donc obligé d'utiliser la réflexion et de rechercher les méthodes de conversion générées par le compilateur et d'invoquer vous-même vous-même.

Si vous pouvez contrôler les types que vous avez besoin de cet opérateur de conversion ( chien dans l'exemple), je pense que vous devriez partir des opérateurs de conversion de la compilée et créer une option plus respectueuse de l'exécution. (Vous pouvez également utiliser des deux cours): xxx

vous vérifiez comme suit ceci: xxx

ou ceci: < / p> xxx


0 commentaires