Use “Optional, DefaultParameterValue” attribute, or not?

荒凉一梦 提交于 2019-12-05 12:05:51

问题


Is there any difference between using Optional and DefaultParameterValue attributes and not using them?

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

public void Test2(string p1= "param1", string p2= "param2")
{
}

both work:

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

回答1:


The difference is that by using the attributes explicitly, the compiler doesn't enforce the same strictness on type requirements.

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(); }
}

Note that even with DefaultParameterValue, you don't throw out type-safety: if the types are incompatible, this will still be flagged.

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) { }
}



回答2:


They compile identically, and the compiler works fine with either. The only difference is the lack of using System.Runtime.InteropServices;, and easier to read code.

For reference, the IL is:

.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 
}

where TheName is the only thing that changes.




回答3:


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;
    }
}

They are doing the same job. You can check things like this in Roslyn or in ReferenceSource



来源:https://stackoverflow.com/questions/40171095/use-optional-defaultparametervalue-attribute-or-not

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!