2012-07-04 38 views
12

Tôi đang cố gắng để mã hóa một phương pháp mở rộng LINQ MinByC# kiểm tra nếu biến giao

public static class Extensions 
{ 
    public static T MinBy<T>(this IEnumerable<T> source, Func<T,int> selector) 
    { 
     T min; 
     int? minKey = null; 
     foreach (var x in source) 
     { 
      var key = selector(x); 
      if (minKey == null || key < minKey) 
      { 
       minKey = key; 
       min = x; 
      } 
     } 
     if (minKey == null) 
     { 
      throw new ArgumentException("source should not be empty"); 
     } 
     return min; 
    } 
} 

Tôi nghĩ logic của tôi là chính xác và dễ đọc. Nhưng tôi nhận được một build lỗi

Sử dụng unassigned địa phương biến 'phút'

Tôi có thể làm gì về điều này? Tôi có thể kiểm tra nếu biến được gán không?


Làm rõ: Chức năng MinBy có thể trả lời câu hỏi sau. Số nào trong số [-5, -2, 3] có hình vuông nhỏ nhất?

> new List<int>{-5,-2,3}.MinBy(x => x*x) 
-2 

Min chức năng NET của câu trả lời một câu hỏi khác nhau (đó là nhỏ nhất của các hình vuông)

> new List<int>{-5,-2,3}.Min(x => x*x) 
4 
+0

IQueryable <> thậm chí còn tốt hơn IEnumerable <> imho cho việc này. – Alex

+0

Tôi có thể truy xuất được gì? –

+0

Kiểm tra nó trên MSDN, đó là một loại bộ sưu tập cho phép truy vấn chuỗi, rất mạnh mẽ. – Alex

Trả lời

23

Bạn cần một giá trị mặc định cho min như thế này:

T min = default(T);

You can read more about default() on MSDN:

Với biến t của kiểu T được tham số hóa, câu lệnh t = null chỉ hợp lệ nếu T là kiểu tham chiếu và t = 0 sẽ chỉ hoạt động cho loại giá trị số chứ không phải cho cấu trúc. Giải pháp là sử dụng từ khóa mặc định , sẽ trả về giá trị rỗng cho các loại tham chiếu và số không cho các loại giá trị số. Đối với cấu trúc, nó sẽ trả về mỗi thành viên của cấu trúc được khởi tạo thành 0 hoặc null tùy thuộc vào việc chúng là giá trị hoặc loại tham chiếu. Đối với các kiểu giá trị nullable, mặc định trả về một hệ thống .Không thể khởi tạo, được khởi tạo giống như bất kỳ cấu trúc nào.

+0

Cảm ơn. Điều này có phá vỡ logic của tôi không? Sau một chút suy nghĩ, không. –

1

Đó là vì min được chỉ định bên trong điều kiện. Trình biên dịch không thể xác định xem nó sẽ nhận được một giá trị hay không, bạn nên khởi tạo min với giá trị default.

4

Thêm một giá trị mặc định cho min:

T min = default(T); 

Lý do nó phàn nàn là trình biên dịch không thể xác minh rằng min sẽ được gán một giá trị trước khi nó được sử dụng trong dòng return min;. Một biến cục bộ chưa được gán không thể được tham chiếu, và do đó trình biên dịch tạo ra một lỗi.

-1

FYI này là những gì tôi đã kết thúc với

public static T MinBy<T>(this IEnumerable<T> source, Func<T,int> selector) 
    { 
     T min = default(T); 
     bool started = false; 
     int minKey = default(int); 
     foreach (var x in source) 
     { 
      var key = selector(x); 
      if (!started || key < minKey) 
      { 
       minKey = key; 
       min = x; 
       started = true; 
      } 
     } 
     if (!started) 
     { 
      throw new ArgumentException("source should not be empty","source"); 
     } 
     return min; 
    } 
-1

Không, bạn không thể kiểm tra xem một biến được gán, bạn sẽ luôn nhận được một lỗi biên dịch.

Các vấn đề liên quan