2009-08-09 4 views
13

En tant qu'opérateurs C# par ex. +, + =, == sont substituables. Cela me permet de penser qu'ils sont une sorte de méthode, donc je me demande s'il existe un moyen de les appeler en utilisant la réflexion, sur Int32 par exemple.Est-il possible d'appeler des opérateurs de type valeur par réflexion?

+6

Les opérateurs ne peuvent pas être * remplacés *. Ils peuvent être * surchargés *. Il y a une grande différence. –

+1

Pour être plus clair, le remplacement permet de redéfinir l'implémentation, la surcharge permet d'ajouter une autre méthode avec le même nom mais avec des paramètres différents. Merci pour la remarque. –

+0

Répondu au commentaire et ajouté un exemple non-typé. –

Répondre

7

Oui, les opérateurs personnalisés sont invocables en utilisant la réflexion (ils ont des noms spéciaux, tels que op_Addition), mais System.Int32 ne les définit pas, car les types fondamentaux intégrés sont gérés directement par les opcodes IL comme add plutôt que des appels de méthode.

+1

que sont les opérateurs de distribution personnalisés? –

+1

Answer propre sous-question - s'avère qu'ils sont "op_Implicit" et "op_Explicit" et peut avoir plusieurs versions avec le même nom, ne différant que par le type de retour. –

0

Il serait très inefficace si l'ajout ou la comparaison de deux entiers nécessitait un appel de méthode, donc ces opérations simples sur les types fondamentaux sont générées par code comme expliqué dans une autre réponse et ne peuvent pas être appelées par réflexion. Un type de valeur intégré intéressant est decimal (ou System.Decimal). Ce struct prend en charge les valeurs littérales en C#, mais se comporte beaucoup comme un type de valeur réel et expose beaucoup d'opérateurs pouvant être invoqués via la réflexion.

Si vous êtes curieux, vous pouvez utiliser Reflector pour parcourir tous les membres de System.Int32.

0

Il y a de bonnes réponses ici, donc il suffit d'ajouter quelque chose non encore mentionné:

Un struct pourrait avoir un operator overloaded. Cela signifie plus d'options pour vérifier si vous essayez de créer une approche programmatique.

Une bonne chose à essayer est d'essayer l'approche de l'arbre d'expression. Here est un petit échantillon. Bien sûr, la performance n'est pas très bonne, mais nous savons de quoi nous parlons avec Reflection, de toute façon.

4

Qu'est-ce que vous voulez exactement faire? Traiter les différentes significations des opérateurs (primitives (mappées à des instructions IL spécifiques), personnalisées (mappées à des méthodes statiques) et levées (fournies comme un modèle par le compilateur) rendent cela douloureux. Si vous voulez juste utiliser les opérateurs, alors il est possible d'écrire du code qui fournit un support opérateur via génériques. J'ai un code pour cela qui est librement disponible dans MiscUtil (description and examples).


À titre d'exemple typées (une note que ce n'est pas extrêmement efficace, mais fonctionne):

object x = 123, y = 345; // now forget that we know that these are ints... 
object result = Expression.Lambda<Func<object>>(
    Expression.Convert(Expression.Add(
     Expression.Constant(x), Expression.Constant(y)), 
    typeof(object))).Compile()(); 
+0

En fait, je voulais implémenter un Add (objet à gauche, objet à droite) où la valeur retournée utilise le type de l'argument left. C'est pour une évaluation d'expression, et comme il est dynamique il n'y a aucun moyen d'écrire le code directement. –

+1

Dans ce cas, vous allez adorer 'dynamic' dans 4.0 - il fera à peu près ceci ... –

+0

être en désaccord sur l'option pour 4.0 puisque le travail de Seb est focalisé sur l'amélioration de la performance par rapport à Expression Trees bloat et invention. A en juger par les performances du DLR et de ses bits qui le contiennent, il ne fait que rendre le PDC imminent le cadre le plus lent de l'histoire de l'humanité. –

8

Qu'en est-ce, il est simple, petit et fonctionne :)

public T Add<T>(object x, object y) 
{ 
    return (T)Convert.ChangeType((dynamic)x + (dynamic)y, typeof(T)); 
} 
+0

Cela a fonctionné magnifiquement dans mon application. La première fois que j'ai vraiment utilisé "dynamique" aussi. J'aime ça! – Boinst

Questions connexes