parametros parameter opcionales make c# c#-4.0 optional-parameters

c# - opcionales - Utilice el atributo "Optional, DefaultParameterValue", o no?



optional parameter c# string (3)

¿Hay alguna diferencia entre usar los atributos Optional y DefaultParameterValue y no usarlos?

public void Test1([Optional, DefaultParameterValue("param1")] string p1, [Optional, DefaultParameterValue("param2")] string p2) { } public void Test2(string p1= "param1", string p2= "param2") { }

ambos trabajan:

Test1(p2: "aaa"); Test2(p2: "aaa");


La diferencia es que al usar los atributos explícitamente, el compilador no impone la misma rigurosidad en los requisitos de tipo.

public class C { // accepted public void f([Optional, DefaultParameterValue(1)] object i) { } // error CS1763: ''i'' is of type ''object''. A default parameter value of a reference type other than string can only be initialized with null //public void g(object i = 1) { } // works, calls f(1) public void h() { f(); } }

Tenga en cuenta que incluso con DefaultParameterValue , no descarta la seguridad de tipos: si los tipos son incompatibles, esto todavía estará marcado.

public class C { // error CS1908: The type of the argument to the DefaultParameterValue attribute must match the parameter type //public void f([Optional, DefaultParameterValue("abc")] int i) { } }


Se compilan de forma idéntica, y el compilador funciona bien con cualquiera. La única diferencia es la falta de using System.Runtime.InteropServices; , y mas facil de leer codigo.

Para referencia, la IL es:

.method public hidebysig instance void TheName([opt] string p1, [opt] string p2) cil managed { .param [1] = string(''param1'') .param [2] = string(''param2'') .maxstack 8 L_0000: ret }

donde TheName es lo único que cambia.


namespace System.Runtime.InteropServices { using System; // // The DefaultParameterValueAttribute is used in C# to set // the default value for parameters when calling methods // from other languages. This is particularly useful for // methods defined in COM interop interfaces. // [AttributeUsageAttribute(AttributeTargets.Parameter)] public sealed class DefaultParameterValueAttribute : System.Attribute { public DefaultParameterValueAttribute(object value) { this.value = value; } public object Value { get { return this.value; } } private object value; } }

Ellos están haciendo el mismo trabajo. Puede verificar cosas como esta en Roslyn o en ReferenceSource