Giả sử tôi có một lớp:Tại sao các đối số biểu thức lambda không rõ ràng giữa Func và Biểu thức <Func>?
class MyClass {
public int MyMethod(Func<int, int> f) { return 0; }
public int MyMethod(Expression<Func<int, int>> f) { return 1; }
}
Khi tôi cố gắng gọi phương thức với một biểu thức lambda, tôi nhận được một lỗi biên dịch nói rằng các cuộc gọi là mơ hồ giữa hai định nghĩa chồng:
var myClass = new MyClass();
myClass.MyMethod(x => 1 + x); // Error!
trong khi, tất nhiên, gọi bằng một loại rõ ràng hoạt động tốt:
myClass.MyMethod((Func<int, int>)(x => 1 + x)); // OK, returns 0
myClass.MyMethod((Expression<Func<int, int>>)(x => 1 + x)); // OK, returns 1
Cây biểu thức chứa nhiều thông tin hơn (mã thực tế) và tôi có thể đợi nt để sử dụng thông tin này khi có sẵn. Nhưng tôi cũng muốn mã của tôi làm việc với các đại biểu. Thật không may, sự mơ hồ này làm cho nó vì vậy tôi phải tìm một cách khác để phân biệt giữa hai cuộc gọi, mà messes lên một API khác sạch sẽ.
Thông số C# không nói bất cứ điều gì về tình huống cụ thể này, do đó, theo nghĩa này, hành vi không khớp với thông số.
Tuy nhiên, có một đối số được thực hiện rằng cây biểu thức nên được ưu tiên hơn đại biểu. Phương thức Compile
hoạt động như một chuyển đổi rõ ràng từ cây biểu thức cho một đại biểu. Cây biểu thức chứa nhiều thông tin hơn và khi bạn biên dịch cho một đại biểu, bạn sẽ mất thông tin đó. Không có chuyển đổi theo hướng khác.
Có bất kỳ lý do nào không thích cây biểu thức không?
Đối số có lợi cho 'Func' là bạn có thể thực hiện trực tiếp mà không phải trải qua giai đoạn khen ngợi tương đối đắt tiền. – Lee