2010-06-10 24 views
11

Este es el trato. Tengo un programa que cargará un ensamblaje determinado, analizará todos los tipos y sus miembros, compilará TreeView (muy similar al antiguo sitio MSDN) y luego compilará páginas HTML para cada nodo en TreeView. Básicamente, toma un ensamblaje determinado y permite al usuario crear su propia biblioteca similar a MSDN para fines de documentación.Sobrecargas de reflexión y operador en C#

Aquí está el problema que me he encontrado: siempre que una sobrecarga del operador se codifica en una clase definida, reflection la devuelve como "MethodInfo" con el nombre establecido como "op_Assign" u "op_Equality". Quiero ser capaz de capturarlos y listarlos correctamente, pero no puedo encontrar nada en el objeto MethodInfo que se devuelve para identificar con precisión que estoy mirando a un operador.

Definitivamente no quiero capturar todo lo que comienza con "op_", ya que con certeza (en algún momento) se detectará un método que se supone que no debe. Sé que otros métodos y propiedades que son "casos especiales" como este tienen la propiedad "IsSpecialName" establecida, pero aparentemente ese no es el caso con los operadores.

He estado recorriendo la red y agitando mi cerebro durante dos días tratando de resolver esto, por lo que cualquier ayuda será muy apreciada.

+0

El proyecto NRefactory es relevante aquí. Tiene métodos de análisis para ayudar con esto. https://github.com/icsharpcode/NRefactory/blob/master/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs – yoyo

Respuesta

16

La convención op_ naming es un estándar estándar o de hecho para .net. Al reflexionar, me gustaría hacer algo como esto:

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 se encenderá todos los operadores sobrecargable (no se olvide conversiones implícitas y explícitas). Si el nombre del método no es uno de los nombres de operador estándar, llama a GenerateDocForStandardMethod. No pude encontrar una lista exhaustiva de los nombres de los métodos del operador, pero probablemente podría proporcionar una lista completa si realmente la necesita.

EDIT: He aquí una lista de los nombres de los métodos de operadores sobrecargable (tomado 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_BitwiseY
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_Decrement
op_Increment
op_UnaryNegation
op_UnaryPlus
op_OnesComplement

+0

Esa es una gran idea de cómo manejarlo, en realidad. Gracias. Supongo que me obsesioné demasiado por encontrar un valor de definición para identificar al operador. A propósito, me pregunto qué pasaría si hiciera una clase con una sobrecarga de operador adicional * y * un método aleatorio llamado "op_Addition". Me pregunto si el compilador te dejará hacer eso.Suena como un experimento para los próximos minutos :) Gracias, otra vez. ¿Pasar para saber dónde puedo obtener una lista de todos los posibles valores op_XXXX? –

+0

Tuve problemas para encontrar la lista, también. Rock :) –

+2

Mike U: Simplemente porque tenía curiosidad por el resultado: No compila si define un método llamado como el operador: Tipo 'Foo' ya define un miembro llamado 'op_Addition' con los mismos tipos de parámetros – NobodysNightmare

5

sobrecargas de operadores reciben la bandera IsSpecialName establece en true. Y si implementa los métodos explícitamente dándoles un nombre como op_ * ese indicador se establece en falso.

2

Para agregar al post de la Wiser: el mismo hilo (http://forums.devx.com/showthread.php?55322-Operator-Overloading.....C-can-do-it....&p=208952#post208952) menciona algunos operadores operadores adicionales:

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 

Estos operadores se ven en el Common Language Infrastructure anotado libro estándar: 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

Algunos útil tabla también se puede encontrar aquí: http://en.csharp-online.net/Common_Type_System%E2%80%94Operator_Overloading

+0

Nota: todos estos pueden usarse para * algunos lenguajes de framework * .NET, pero de esta lista el compilador C * * solo aprovecha los operadores LogicalNot, True y False. Y prefiere 'operador implícito bool' a los operadores True y False, si ambos están definidos. – aboveyou00