2010-06-10 3 views
11

Voici l'affaire. J'ai un programme qui va charger un assembly donné, analyser tous les types et leurs membres et compiler un TreeView (très similaire à l'ancien site MSDN), puis construire des pages HTML pour chaque nœud dans le TreeView. Il prend essentiellement un assembly donné et permet à l'utilisateur de créer sa propre bibliothèque de type MSDN à des fins de documentation.Surcharge et réflexion de l'opérateur en C#

Voici le problème que j'ai rencontré: lorsqu'une surcharge d'opérateur est enchaînée dans une classe définie, la réflexion renvoie celle-ci en tant que "MethodInfo" avec le nom défini sur quelque chose comme "op_Assign" ou "op_Equality". Je veux être capable de les capturer et de les répertorier correctement, mais je ne trouve rien dans l'objet MethodInfo retourné pour identifier précisément que je regarde un opérateur. Je ne veux définitivement pas capturer tout ce qui commence par "op_", car cela va sûrement (à un certain point) ramasser une méthode à laquelle il n'est pas supposé. Je sais que d'autres méthodes et propriétés qui sont des "cas spéciaux" comme celui-ci ont la propriété "IsSpecialName" définie, mais apparemment ce n'est pas le cas avec les opérateurs. J'ai fait du récurage sur le net et j'ai creusé mon cerveau à deux jours en essayant de comprendre celui-ci, donc toute aide sera grandement appréciée.

+0

Le projet NRefactory est pertinent ici. Il a des méthodes d'analyse pour aider avec cela. https://github.com/icsharpcode/NRefactory/blob/master/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs – yoyo

Répondre

16

La convention de nommage op_ est une norme standard ou de facto pour .net. En réfléchissant, je ferais quelque chose comme ceci:

public void GenerateDocForMethod(MethodInfo method) 
{ 
    if(method.Name.StartsWith("op_")) 
     GenerateDocForOperator(method); 
    else 
     GenerateDocForStandardMethod(method); 
} 

public void GenerateDocForOperator(MethodInfo method) 
{ 
    switch(method.Name) 
    { 
     case "op_Addition": 
     //generate and handle other cases... 

     //handle methods that just happen to start with op_ 
     default: 
      GenerateDocForStandardMethod(method); 
    } 
} 

public void GenerateDocForStandardMethod(MethodInfo method) 
{ 
    //generate doc 
} 

GenerateDocForOperator basculera sur tous les opérateurs surchargeables (ne pas oublier les conversions implicites et explicites). Si le nom de la méthode ne fait pas partie des noms d'opérateurs standard, il appelle GenerateDocForStandardMethod. Je n'ai pas trouvé de liste exhaustive des noms de méthodes d'opérateurs, mais je pourrais probablement vous fournir une liste complète si vous en avez vraiment besoin.

EDIT: Voici une liste des noms des méthodes des opérateurs surchargeables (prise de http://forums.devx.com/showthread.php?55322-Operator-Overloading.....C-can-do-it....&p=208952#post208952):

op_Implicit
op_Explicit
op_Addition
op_Subtraction
op_Multiply
op_Division
op_Modulus
op_ExclusiveOr
op_BitwiseAnd
op_BitwiseOr

op_LogicalAnd op_LogicalOr

op_Assign op_LeftShift

op_RightShift op_SignedRightShift

op_UnsignedRightShift op_Equality

op_GreaterThan op_LessThan

op_Inequality op_GreaterThanOrEqual
op_LessThanOrEqual

op_MultiplicationAssignment op_SubtractionAssignment

op_ExclusiveOrAssignment op_LeftShiftAssignment

op_ModulusAssignment op_AdditionAssignment

op_BitwiseAndAssignment op_BitwiseOrAssignment

op_Comma op_DivisionAssignment

op_Decrementop_Increment
op_UnaryNegation
op_UnaryPlus
op_OnesComplement

+0

C'est une bonne idée de la façon de le gérer, en fait. Merci. Je suppose que j'ai trop raccroché pour trouver une valeur déterminante pour identifier l'opérateur. Incidemment, je me demande ce qui se passerait si je faisais une classe avec une surcharge d'opérateur d'addition * et * une méthode aléatoire appelée "op_Addition". Je me demande si le compilateur vous laissera faire ça?On dirait une expérience pour les prochaines minutes :) Merci encore. Je suis arrivé à savoir où je peux obtenir une liste de toutes les valeurs op_XXXX possibles? –

+0

J'ai aussi eu du mal à trouver la liste. You rock :) –

+2

Mike U: Juste parce que j'étais curieux du résultat: Il ne compile pas si vous définissez une méthode appelée comme l'opérateur: Le type 'Foo' définit déjà un membre appelé 'op_Addition' avec les mêmes types de paramètres – NobodysNightmare

5

opérateur font surcharge obtenir le drapeau IsSpecialName à true. Et si vous implémentez les méthodes en leur donnant explicitement un nom comme op_ *, cet indicateur est défini sur false.

2

Pour ajouter au poste de la Wiser: le même fil (http://forums.devx.com/showthread.php?55322-Operator-Overloading.....C-can-do-it....&p=208952#post208952) mentionne certains opérateurs opérateurs supplémentaires:

Some additions - see CLI Partition 1, section 10.3. 
op_UnsignedRightShiftAssignment 
op_RightShiftAssignment 
op_MemberSelection 
op_PointerToMemberSelection 
op_LogicalNot 
op_True 
op_False 
op_AddressOf 
op_PointerDereference 

Ces opérateurs sont vus dans le Common Language Infrastructure Annotated livre standard: http://books.google.ru/books?id=50PhgS8vjhwC&pg=PA111&lpg=PA111&dq=op_PointerToMemberSelection&source=bl&ots=vZIC0nA9sW&sig=4hTfAAWGkaKirgBQ4I1yBnK_D2M&hl=en&sa=X&ei=YsB2ULvAMuHx4QT25YCYAw&ved=0CB0Q6AEwAA#v=onepage&q=op_PointerToMemberSelection&f=false

Certains à portée de main La table peut également être trouvée ici: http://en.csharp-online.net/Common_Type_System%E2%80%94Operator_Overloading

+0

Remarque: tous ces éléments peuvent être utilisés pour * certains * langages de framework .NET, mais dans cette liste, le compilateur C# * seulement * tire parti des opérateurs LogicalNot, True et False. Et il préfère 'l'opérateur implicite bool' aux opérateurs True et False, si les deux sont définis. – aboveyou00