2016-10-21 5 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相互運用コードの作成に役立ちました。引数は、それを見るためのデフォルトなしのオブジェクトでなければならないでしょう、そして、呼び出し側はType.Missingを渡します。提供された構文を使用して、砂糖はもちろん常に最高です。 –

答えて

7

の違いを確認することができます。違いは、属性を明示的に使用することによって、コンパイラはタイプ要件に同じ厳密性を強制しないことです。

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

でもDefaultParameterValueで、あなたは型の安全性を捨てていないことに注意してください。タイプは互換性がない場合、これはまだフラグが付けられます。

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

関連する問題