c# - polimorfico - Cómo pasar objetos a un constructor de atributos
pasar objeto como parametro c# (3)
Estoy intentando pasar objetos a un constructor de Atributos de la siguiente manera:
[PropertyValidation(new NullOrEmptyValidatorScheme())]
public string Name { get; private set; }
Con este constructor de atributos:
public PropertyValidationAttribute(IValidatorScheme validator) {
this._ValidatorScheme = validator;
}
El código no se compilará ¿Cómo puedo pasar un objeto a un atributo como el anterior?
EDITAR: Sí NullOrEmptyValidatorScheme implementa IValidatorScheme.
El error: error CS0182: un argumento de atributo debe ser una expresión constante, tipo de expresión o expresión de creación de matriz de un tipo de parámetro de atributo.
Como se observó en los carteles anteriores, los tipos de uso en los argumentos de los atributos están bastante restringidos (comprensiblemente, porque sus valores deben ser serializados directamente en el blob de metadatos del ensamblaje).
Dicho esto, probablemente puedas crear una solución que utilice typeofs , ya que se pueden usar.
Por ejemplo :
[PropertyValidation(typeof(NullOrEmptyValidatorScheme))]
public string Name { get; private set; }
Esta sintaxis es perfectamente legal. El código que lee sus atributos tiene que obtener el tipo de validador, crear una nueva instancia del validador (incluso puede mantener un caché de validadores codificados en los tipos del valicador, si corresponde, esta es una técnica bastante común), y luego invocarlo .
Los valores en atributos están limitados a tipos simples; por ejemplo, constantes básicas (incluidas cadenas) y typeof
... no puede usar código new
u otro más complejo. En breve; no puedes hacer esto Puedes darle el tipo sin embargo:
[PropertyValidation(typeof(NullOrEmptyValidatorScheme)]
es decir, el Ctor de Validación de PropertyValidation
toma un Type
y usa Activator.CreateInstance
dentro del código para crear el objeto. Tenga en cuenta que lo ideal es que simplemente almacene la cadena internamente ( AssemblyQualifiedName
).
De ECMA 334v4:
§24.1.3 Tipos de parámetros de atributos
Los tipos de parámetros posicionales y nominales para una clase de atributo están limitados a los tipos de parámetros de atributo , que son:
- Uno de los siguientes tipos:
bool
,byte
,char
,double
,float
,int
,long
,short
,string
.- El tipo de
object
- El tipo
System.Type
.- Un tipo de enumeración, siempre que tenga acceso público y los tipos en los que está anidado (si lo hay) también tienen acceso público.
- Arrays unidimensionales de los tipos anteriores.
y
§24.2 Especificación de atributo
...
Una expresión
E
es una expresión de argumento-atributo si todas las siguientes afirmaciones son verdaderas:
- El tipo de
E
es un tipo de parámetro de atributo (§24.1.3).- En tiempo de compilación, el valor de E se puede resolver a uno de los siguientes:
- Un valor constante.
- Un tipo de expresión (§14.5.11) que especifica un tipo no genérico, un tipo construido cerrado (§25.5.2), o un tipo genérico no vinculado (§25.5).
- Una matriz unidimensional de expresiones de argumento-atributo.
Además ... (Creo que es un error de Microsoft)
No puede poner un valor predeterminado en "nulo", pero el valor predeterminado simple predeterminado es correcto (''falso'', ''7'', ''"Prueba").
El ejemplo NExt le dará el siguiente error: Un argumento de atributo debe ser una expresión constante, tipo de expresión o expresión de creación de matriz de un tipo de parámetro de atributo
en archivo: ... / CSC
public class SampleAttribute : Attribute
{
private string _test;
public SampleAttribute(string test = null)
{
_test = test;
}
}
[Sample]
public class Toto
{
}