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