c# - parametros - El argumento de atributo debe ser un error constante cuando se usa un parámetro opcional en el constructor de atributo
parametros opcionales c# (2)
¿Alguien puede explicar por qué funciona este código?
public class AdministratorSettingValidationAttribute : Attribute
{
public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType)
{
DataType = administratorSettingDataType;
}
public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType, Type enumerationType)
{
DataType = administratorSettingDataType;
EnumerationType = enumerationType;
}
}
... pero refactorizándolo para usar un parámetro opcional en su lugar:
public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType, Type enumerationType = null)
{
DataType = administratorSettingDataType;
EnumerationType = enumerationType;
}
... provoca un error de tiempo de compilación: " 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 ".
ACTUALIZAR
El error fue reportado en julio del año pasado y ya está arreglado. La solución aparecerá en la próxima versión de C #. Ver este elemento de comentarios Conectar para más detalles:
Eso es claramente un error de compilación. Gracias por llamar mi atención.
Lo que se supone que sucede aquí es que se supone que el compilador se da cuenta de que la expresión de valor opcional se convierte implícitamente al tipo de parámetro formal, y luego trata la expresión como una expresión constante de ese tipo. Lo que realmente está haciendo es tratar la expresión como un literal nulo sin tipo, lo que está mal.
Puede solucionar el error convirtiendo la constante en una explícitamente escrita:
public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType, Type enumerationType = (Type)null)
La solución es probablemente sencilla pero no puedo prometer que la solución estará en la próxima versión de C #; No estoy seguro de cómo es la programación para tomar correcciones de errores no críticos en este momento.
Gracias de nuevo, y disculpas por las molestias.
Esto me huele a error de compilación. Las clases de atributos son clases ''especiales'' de manera que pueden usarse como metadatos. El compilador de C # le permite usarlos de manera diferente a las clases normales y, por lo tanto, podemos asumir que existe una implementación personalizada (parcial) para compilar el uso de clases de atributos en el compilador de C #. (¿Alguien puede probar esto en mono?)
Dicho esto, hice algunas pruebas y descubrí que solo cuando utilizaba el constructor de un atributo que especifica el valor predeterminado de un parámetro como nulo sin definir un valor personalizado de ese atributo, el compilador nos da un error. Mi código de prueba:
class TestAttribute : Attribute
{
public TestAttribute(object test = null) { }
//public TestAttribute(int test = 0) { }
public void TestMethod(object test = null) { }
}
class TestClass
{
public TestClass(object test = null) { }
}
[Test()] // crashes
//[Test()] // Works when using the constructor taking an int
//[Test(null)] // works
class Program
{
static void Main(string[] args)
{
TestClass t = new TestClass(); // works
TestAttribute a = typeof(Program).GetCustomAttributes(typeof(TestAttribute), false).Cast<TestAttribute>().First();
a.TestMethod(); // works
}
}
(Probado con VS 2010 bajo .NET 4.0, ¿alguien puede probar esto con mono?)
Tenga en cuenta que los atributos ya le permiten abordar las propiedades como si fueran opcionales, por lo que podría hacer que su parámetro opcional sea una propiedad (si no lo está ya, y eliminarlo del constructor. Esto aún le permite escribir [Prueba (nula, MiPropiedad = nula )]