es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo evaluar completamente los parámetros de un atributo en un generador de código fuente de C#?

En un generador de código fuente, encontré un atributo en una clase y resolví su FQN con GeneratorSyntaxContext.SemanticModel para, por ejemplo, lidiar con el hecho de que su nombre se escriba con o sin “Attribute”. ¿Cómo puedo resolver los argumentos? Básicamente quiero manejar todos estos casos:

// class MyAttribute : Attribute
// {
//   public MyAttribute(int first = 1, int second = 2, int third = 3) {...}
//   string Property {get;set;}
// }

[My]
[MyAttribute(1)]
[My(second: 8 + 1)]
[My(third: 9, first: 9)]
[My(1, second: 9)]
[My(Property = "Bl" + "ah")] // Extra, puedo prescindir de esto, pero sería agradable

La mayoría del código que pude encontrar, incluidos los ejemplos oficiales, simplemente codifica en duro ArgumentList[0], [1], etc. y el nombre del atributo escrito en “forma corta”. Obtener el objeto del atributo en sí o una copia idéntica sería ideal (no está inyectado por el generador de código fuente, sino que se referencia de ProjectReferenced “normalmente”, por lo que el tipo está disponible), pero podría estar más allá de Roslyn, así que simplemente evaluar las constantes y averiguar qué valor va a dónde es suficiente.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para resolver los argumentos de un atributo en un generador de código fuente, se puede usar el método GetSymbolInfo del SemanticModel para obtener el IMethodSymbol del constructor del atributo. Una vez que se tiene el IMethodSymbol, se puede utilizar su propiedad Parameters para obtener información sobre los parámetros del constructor, incluyendo sus nombres y valores por defecto.

    Para manejar todas las diferentes formas en que se puede utilizar el atributo, se debe utilizar el AttributeData obtenido del SyntaxNode que representa el atributo. Luego se puede iterar sobre AttributeData.ConstructorArguments y AttributeData.NamedArguments para obtener los valores de los argumentos en el orden en que fueron especificados o por sus nombres, respectivamente.

    Para manejar el caso de los argumentos con expresiones (como Property = "Bl" + "ah"), se puede utilizar el SemanticModel para evaluar la expresión y obtener su valor resultante.

    En resumen, el proceso involucraría los siguientes pasos:

    1. Obtener el AttributeData del atributo llamando a SemanticModel.GetSymbolInfo en el SyntaxNode que representa el atributo.

    2. Obtener el IMethodSymbol del constructor del atributo llamando a AttributeData.AttributeConstructor.

    3. Obtener la lista de parámetros del constructor desde la propiedad IMethodSymbol.Parameters.

    4. Iterar sobre AttributeData.ConstructorArguments para obtener los argumentos ordenados. Para cada argumento, utilizar la propiedad Value para obtener su valor. Si el argumento es una expresión, utilizar el SemanticModel para evaluar la expresión y obtener su valor resultante.

    5. Iterar sobre AttributeData.NamedArguments para obtener los argumentos con nombres. Para cada argumento, utilizar la propiedad Value para obtener su valor. Si el argumento es una expresión, utilizar el SemanticModel para evaluar la expresión y obtener su valor resultante.

    6. Utilizar la información obtenida en los pasos 3-5 para manejar el atributo de la manera deseada.

Comments are closed.