Eric Lippert đã viết một loạt bài xuất sắc về những hạn chế (và các quyết định thiết kế ảnh hưởng đến những lựa chọn đó) trên các khối trình lặp
Đặc biệt, các khối trình lặp cụ thể được thực hiện bởi một số biến đổi mã trình biên dịch phức tạp. Những biến đổi này sẽ tác động đến các biến đổi xảy ra bên trong các hàm hoặc lambdas ẩn danh để trong một số trường hợp nhất định, cả hai sẽ cố gắng 'chuyển đổi' mã thành một số cấu trúc khác không tương thích với cấu trúc kia.
Do đó, họ bị cấm tương tác.
Cách khối vòng lặp hoạt động dưới mui xe được giải quyết tốt ở đây .
Như một ví dụ đơn giản về sự không tương thích:
public IList<T> GreaterThan<T>(T t)
{
IList<T> list = GetList<T>();
var items = () => {
foreach (var item in list)
if (fun.Invoke(item))
yield return item;
}
return items.ToList();
}
Trình biên dịch đồng thời muốn chuyển đổi điều này thành một cái gì đó như:
private class Magic
{
private T t;
private IList<T> list;
private Magic(List<T> list, T t) { this.list = list; this.t = t;}
public IEnumerable<T> DoIt()
{
var items = () => {
foreach (var item in list)
if (fun.Invoke(item))
yield return item;
}
}
}
public IList<T> GreaterThan<T>(T t)
{
var magic = new Magic(GetList<T>(), t)
var items = magic.DoIt();
return items.ToList();
}
và đồng thời khía cạnh trình lặp đang cố gắng thực hiện nó hoạt động để tạo ra một máy trạng thái nhỏ. Một số ví dụ đơn giản nhất định có thể hoạt động với một lượng lớn kiểm tra tỉnh táo (trước tiên xử lý các đóng lồng nhau (có thể tùy ý)), sau đó xem liệu các lớp kết quả ở cấp cuối cùng có thể được chuyển đổi thành các máy trạng thái trình vòng lặp hay không.
Tuy nhiên đây sẽ là
- Khá nhiều công việc.
- Không thể hoạt động trong mọi trường hợp nếu không có ít nhất khía cạnh khối trình vòng lặp có thể ngăn khía cạnh đóng áp dụng các phép biến đổi nhất định để có hiệu quả (như quảng bá các biến cục bộ thành các biến cá thể thay vì một lớp đóng hoàn toàn chính thức).
- Nếu thậm chí có một chút cơ hội trùng lặp mà nó không thể hoặc đủ khó để không được thực hiện thì số lượng các vấn đề hỗ trợ dẫn đến có thể sẽ cao vì sự thay đổi nhỏ sẽ bị mất đối với nhiều người dùng.
- Nó có thể rất dễ dàng làm việc xung quanh.
Trong ví dụ của bạn như vậy:
public IList<T> Find<T>(Expression<Func<T, bool>> expression)
where T : class, new()
{
return FindInner(expression).ToList();
}
private IEnumerable<T> FindInner<T>(Expression<Func<T, bool>> expression)
where T : class, new()
{
IList<T> list = GetList<T>();
var fun = expression.Compile();
foreach (var item in list)
if (fun.Invoke(item))
yield return item;
}
async
lambdas ẩn danh cho phépawait
bên trong C # 5.0, tôi muốn biết tại sao họ vẫn chưa triển khai các trình lặp ẩn danh vớiyield
bên trong. Ít nhiều thì nó cũng là một máy phát điện trạng thái.