2012-04-12 7 views
33

Sử dụng AutoMapper, tôi nhấn một nơi mà một cuộc tranh luận tên sẽ đã cho lắp rất độc đáo:Tại sao cây biểu thức không thể chứa thông số đối số được đặt tên?

.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, isAdvanced: false))) 

Nhưng trình biên dịch mắng tôi:

Một cây biểu hiện có thể không chứa một đặc điểm kỹ thuật lập luận tên

Vì vậy, tôi đã phải trở lại:

.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, false))) 

Có ai biết tại sao trình biên dịch không cho phép các đối số có tên trong tình huống này không?

Trả lời

25

xem xét như sau:

static int M() { Console.Write("M"); return 1; } 
static int N() { Console.Write("N"); return 2; } 
static int Q(int m, int n) { return m + n; } 
... 
Func<int> f =()=>Q(n : N(), m: M()); 
Expression<Func<int>> x =()=>Q(n : N(), m: M()); 
Func<int> fx = x.Compile(); 
Console.WriteLine(f()); 
Console.WriteLine(fx()); 

Bạn đồng ý Tôi hy vọng rằng hai dòng cuối cùng phải thực hiện chính xác những điều tương tự, phải không? Đó là để in NM3.

Bây giờ, bạn sẽ thực hiện cuộc gọi thư viện cây biểu thức nào để chuyển đổi cây biểu thức để tạo điều kiện đảm bảo điều này? Không có gì cả! Do đó, chúng tôi phải đối mặt với các lựa chọn sau:

  1. Triển khai tính năng trong thư viện cây biểu thức. Thêm một phép biến đổi trong công cụ hạ thấp cây biểu hiện để duy trì thứ tự thực hiện các đối số đã đặt tên. Triển khai mã theo phương thức Compile để tính đến lệnh thực thi.
  2. Thực hiện x =()=>Q(n : N(), m: M()); thực sự được triển khai dưới dạng x =()=>Q(M(), N()); và không tương thích với phiên bản không phải là biểu thức cây.
  3. Không cho phép đối số được đặt tên trong cây biểu thức. Thực hiện một thông báo lỗi cho hiệu ứng đó.

(1) rất đẹp, nhưng đắt tiền. (2) là không khởi động; chúng ta không thể trong lương tâm tốt giới thiệu loại "gotcha" này. (3) là rẻ nhưng khó chịu.

Chúng tôi đã chọn (3).

+0

Thông báo lỗi này tôi cảm thấy thực sự nên được ghi lại cho ảnh hưởng này. Nói cách khác, tìm kiếm msdn cho chuỗi thông báo lỗi chính xác sẽ cung cấp cho chúng tôi việc làm rõ này. http://social.msdn.microsoft.com/Search/en-US?query=%22An%20expression%20tree%20may%20not%20contain%20a%20named%20argument%20specification%22&ac=8 – payo

+0

Điều này thật tuyệt vời - cảm ơn Eric. Tôi chưa bao giờ thực sự xem xét sự khác biệt giữa 'Biểu thức <...>' và 'Func <...>' cho đến bây giờ. Khi bạn nói rằng (1) sẽ là tốn kém, mặc dù, điều này có nghĩa là về chi phí phát triển hoặc rằng nó sẽ là tốn kém tính toán? –

+1

@BrandonLinton: Sẽ tốn kém để phát triển, kiểm tra, ghi chép và duy trì, đặc biệt khi so sánh với lợi ích rất nhỏ mà nó dành cho nó. Chúng tôi có thể đã chọn để hỗ trợ nó ngay từ đầu - sau khi tất cả, VB đã luôn luôn có tên là đối số cho các cuộc gọi phương pháp - nhưng chúng tôi đã chọn không. –