2016-10-21 4 views
22

OptionalDefaultParameterValue 속성을 사용하는 것과 사용하지 않는 것 사이에 차이가 있습니까?"Optional, DefaultParameterValue"속성을 사용하거나 사용하지 않습니까?

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

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

모두 일 :

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

좋은 질문입니다. 그런 속성이 있는지조차 알지 못했습니다. – HimBromBeere

+1

이 코드를 작성할 때 실제적으로 발생할 가능성은 거의 없습니다. [선택] 속성은 C# 버전 4에서 하이재킹되어보다 쉬운 COM interop 코드 작성을 돕습니다. 인수는 기본값이없는 객체 여야 만합니다. 호출자는 Type.Missing을 전달합니다. 제공된 구문을 사용하면 설탕은 물론 항상 최상입니다. –

답변

7

에서 확인할 수 있습니다. 차이점은 명시 적으로 특성을 사용하면 컴파일러가 형식 요구 사항에 대해 동일한 엄격함을 적용하지 않는다는 것입니다. 종류가 호환되지 않는 경우이 여전히 플래그됩니다 심지어 DefaultParameterValue와 함께, 당신은 유형의 안전을 포기하지

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

참고.

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

그들은 동일하게 컴파일하고 컴파일러 중 하나와 함께 잘 작동합니다. 유일한 차이점은 using System.Runtime.InteropServices;이 부족하여 코드를 읽기 쉽습니다.

참고로, IL은 :

TheName가 만 변경이
.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 
} 

.

+0

@hvd로 답을 확인하십시오. 거의 동일하게 작동하지만 InteropServices는 분명히 유일한 차이점이 아닙니다 **. – Robba

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

그들은 동일한 작업을 수행하고 있습니다. Roslyn이나 ReferenceSource