2013-01-10 18 views
20

Có cách nào để sử dụng optional arguments (tham số mặc định) với lambda expressions trong C#? Tôi đã đọc qua tài liệu nhưng không thể tìm thấy gì để nói theo cách này hay cách khác.Có thể sử dụng tham số tùy chọn/mặc định trong biểu thức lambda trong C# không?

Để minh họa, tôi có thể xác định phương pháp đơn giản mà sử dụng một đối số tùy chọn để cung cấp một giá trị mặc định như vậy:

void MyMethod(string arg = "default-value") 
{ 
    Console.WriteLine(arg); 
} 

Những gì tôi muốn biết là nếu tôi có thể làm điều tương tự bằng cách sử dụng lambda biểu hiện.

// gives a syntax error 
Action<string> MyMethod = (arg = "default") => Console.WriteLine(arg); 

Tôi có thể làm việc trong tham số tùy chọn với giá trị mặc định bằng đại biểu, nhưng điều này có vẻ hơi vụng về.

delegate void MyDelegate(string arg = "default"); 
MyDelegate MyMethod = arg => Console.WriteLine(arg); 

Ngoài ra tôi có thể kiểm tra các thông số trong cơ thể lambda, một cái gì đó giống như ...

Action<string> MyMethod = (arg) => Console.WriteLine(string.IsNullOrEmpty(arg) ? 
            "default" : 
            arg); 

Nhưng một lần nữa này có vẻ hơi vụng về.

Có thể sử dụng tham số tùy chọn để đặt giá trị mặc định trong biểu thức lambda trong C# không?

+0

bản sao có thể có của [Cách chuyển một phương thức với các tham số tùy chọn làm đối số?] (Http://stackoverflow.com/questions/12728844/how-to-pass-a-method-with-optional-parameters-as -an-argument) – horgh

+0

Điều đó không có ý nghĩa. Bạn không thể gọi 'Action ' mà không có đối số. – SLaks

+1

@KonstantinVasilcov - nó không phải là một bản sao ở tất cả - Tôi đặc biệt hỏi về biểu thức lambda - không phải là phương pháp đơn giản. Tôi nghĩ tôi đã làm rõ điều đó, xin lỗi. – Fraser

Trả lời

21

Không. Người gọi (mã gọi người đại diện) không "nhìn thấy" biểu thức lambda, do đó không có nghĩa là chỉ định tham số mặc định ở đó. Tất cả người gọi thấy là người được ủy quyền. Trong trường hợp của bạn, ví dụ, mã gọi chỉ biết về Action<string> - trình biên dịch có nghĩa là biết để cung cấp giá trị mặc định được chỉ định bởi biểu thức lambda như thế nào?

Ví dụ về cách mọi thứ trở nên phức tạp, hãy tưởng tượng nếu điều này khả thi. Sau đó xem xét mã này:

Action<string> action; 
if (DateTime.Today.Day > 10) 
{ 
    action = (string arg = "boo") => Console.WriteLine(arg); 
} 
else 
{ 
    action = (string arg = "hiss") => Console.WriteLine(arg); 
} 
action(); // What would the compiler do here? 

Gấu nhớ rằng đối số được cung cấp bởi trình biên dịch tại địa điểm cuộc gọi - vì vậy những gì nó nên làm gì với dòng cuối cùng?

Giống như có giao diện và triển khai - nếu bạn có thông số mặc định trên giao diện, điều đó là tốt; nếu bạn chỉ có nó về việc triển khai, thì chỉ những người gọi biết về triển khai cụ thể mới thấy được. Trong trường hợp của các biểu thức lambda, thực sự không có triển khai hiển thị nào để người gọi sử dụng: chỉ có chữ ký của đại biểu.

+0

+1 Cảm ơn, điều đó có ý nghĩa. Tôi đã thực sự chỉ cố gắng một cái gì đó và lúc đầu nó có vẻ như nó sẽ làm việc ... – Fraser

2

Chữ lambda sẽ khớp với bất kỳ chữ ký nào của đại biểu được gán cho nó; mà không được gán cho một đại biểu một lambda không thể biên dịch được.

Nếu đại biểu có chứa các đối số tùy chọn thì việc sử dụng đại biểu đó có thể cung cấp các đối số tùy chọn. Nếu đại biểu không, thì việc sử dụng đại biểu đó không thể bỏ qua bất kỳ đối số nào.

Trong khi các đại biểu ActionFunc đại biểu rất tiện dụng và có thể đại diện cho hầu hết chữ ký, họ không thể đại diện bất kỳ chữ ký nào với các đối số tùy chọn; bạn phải sử dụng định nghĩa đại biểu khác cho điều đó.

Remeber, ActionFunc không đặc biệt đặc biệt, chúng chỉ là hai đại biểu mà mọi người sử dụng để họ không cần phải lo lắng về việc tạo riêng cho mọi điều nhỏ nhặt.