2015-07-30 45 views
14

Chỉ cần chạy vào ngày hôm nayTại sao bạn không thể sử dụng chức năng anon với thông số động?

Một chức năng ẩn danh hoặc nhóm phương pháp không thể được sử dụng như một giá trị thành phần của một hoạt động tự động bị ràng buộc.

khi cố gắng làm

static R ifNotNull<R>(dynamic o, Func<dynamic, R> returnFunc, R otherwise) { 
    return ReferenceEquals(null, o) ? otherwise : returnFunc(o); 
} 

và sử dụng nó với

dynamic firstAddress = ...; 
return ifNotNull<string>(firstAddress, (a) => a.address_1, null) 

Bây giờ hầu hết các hạn chế về động thái có ý nghĩa đối với tôi - bạn có thể không sử dụng một phương pháp mở rộng vì thế nào trình biên dịch là gì để quyết định tĩnh để biên dịch nó? Nhưng tôi không nhận được điều này ở đây. Sự nhầm lẫn xuất hiện ở đâu? Chính xác thì hạn chế là gì?

+2

Có lẽ một vấn đề với biên soạn '(a) => a.address_1' thành một 'returnFunc'.Đang chờ Eric Lippert trả lời câu hỏi này :-) – dasblinkenlight

+0

Nhân tiện, sự khác biệt giữa mã của bạn và 'static R ifNotNull (đối tượng o, Func returnFunc, R nếu không) {...}' là gì? – dasblinkenlight

+0

@ dasblinkenlight chính xác những gì tôi đang nghĩ. Chuẩn bị cho Lippert trong 3..2..1 ... –

Trả lời

11

Loại tĩnh của lambaa => a.address_1 là gì? Bạn có thể bị cám dỗ để nói rằng đó là Func<dynamic, dynamic>. Nhưng hãy nhớ:

Biểu thức lambda là một chức năng ẩn danh mà bạn có thể sử dụng để tạo đại biểu hoặc loại biểu thức.

Vì vậy, có thể đó là Expression<Func<dynamic, dynamic>>. Bản thân một lamda không có một kiểu tĩnh đơn lẻ.

Bây giờ kiểu suy luận thông thường sẽ chỉ ra rằng bạn đang chuyển hàm lamba sang hàm có số Func và nó sẽ được chuyển đổi thành đại biểu tại thời gian biên dịch. Tuy nhiên khi bạn đang gọi với các đối số động the method call is dispatched dynamically.

Nếu bạn có cuộc gọi phương thức với đối số động, nó sẽ được gửi đi động, dấu chấm. Trong thời gian ràng buộc thời gian chạy, tất cả các loại tĩnh đối số của bạn được gọi là (nhấn mạnh mỏ) và các loại được chọn cho đối số độngdựa trên giá trị thực tế của chúng.

Vì vậy, thực tế rằng phương pháp của bạn có một số Func không được tính đến, kể từ the actual method call isn't determined until runtime do đó không có suy luận kiểu.

Để có được điều này để biên dịch, bạn sẽ phải đúc lamba của bạn đến một Func<dynamic, string> như sau:

return ifNotNull<string>(firstAddress, new Func<dynamic, string>((a) => a.address_1), null); 

Bây giờ loại tĩnh của lamda của bạn được biết đến.

+0

Cảm ơn bạn đã trả lời kiên quyết. Điều đó có ý nghĩa. Mặc dù tôi vẫn còn hơi bummed tôi đã không nhận được một câu trả lời lippert ... –

1

Tôi có nghĩa là bạn cần phải truyền phương thức lambda đến biểu thức mong muốn bạn muốn. Sau đó, nó sẽ làm việc tốt.

Như thế này:

return ifNotNull(firstAddress, (Func<dynamic, string>)((a) => a.address_1), null); 
Các vấn đề liên quan