2016-10-21 15 views
22

Có sự khác biệt nào giữa việc sử dụng các thuộc tính OptionalDefaultParameterValue và không sử dụng chúng không?Sử dụng thuộc tính "Tùy chọn, Mặc địnhParameterValue" hay không?

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

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

cả công việc:

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

Câu hỏi hay, thậm chí không biết các thuộc tính đó tồn tại. – HimBromBeere

+1

Có, nhưng bạn không có khả năng gặp phải nó trong thực tế khi bạn viết mã như thế này. Thuộc tính [Tùy chọn] bị tấn công trong C# phiên bản 4 để giúp viết mã COM interop dễ dàng hơn. Đối số sẽ phải là đối tượng mà không có mặc định để xem nó, người gọi sau đó vượt qua Type.Missing. Sử dụng đường cú pháp được cung cấp là tất nhiên luôn luôn tốt nhất. –

Trả lời

7

Sự khác biệt là bằng cách sử dụng các thuộc tính một cách rõ ràng, trình biên dịch không thực thi cùng mức độ nghiêm ngặt về các yêu cầu loại.

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

Lưu ý rằng ngay cả với DefaultParameterValue, bạn không vứt bỏ loại an toàn: nếu các loại không tương thích, đây vẫn sẽ được gắn cờ.

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

Họ biên dịch hệt, và trình biên dịch hoạt động tốt với một trong hai. Sự khác biệt duy nhất là thiếu using System.Runtime.InteropServices; và dễ đọc hơn.

Để tham khảo, IL là:

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

nơi TheName là điều duy nhất mà thay đổi.

+0

Kiểm tra câu trả lời bằng @hvd. Trong khi họ làm việc gần như giống nhau, các InteropServices rõ ràng ** không phải là sự khác biệt duy nhất của họ **. – 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; 
    } 
} 

Họ đang làm cùng một công việc. Bạn có thể kiểm tra những thứ như thế này trong Roslyn hoặc trong ReferenceSource

Các vấn đề liên quan