2012-07-04 115 views
12

我想編寫一個LINQ MinBy擴展方法,如果變量分配

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; 
    } 
} 

我覺得我的邏輯是正確的,可讀的C#測試。但我得到一個生成錯誤

使用的未分配的局部變量「分鐘」

我能做些什麼呢?我可以測試變量是否已分配?


說明:MinBy函數可以回答以下問題。哪個數字[-5,-2,3]的平方最小?

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

.NET的Min函數回答不同的問題(這是最小的平方)

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

IQueryable的<>甚至會比IEnumerable的<> IMHO此更好。 – Alex

+0

什麼是IQueryable? –

+0

檢查出來MSDN上,這是一個類型的集合,它允許查詢鏈接,非常強大。 – Alex

回答

23

你需要一個默認值min這樣的:

T min = default(T);

You can read more about default() on MSDN:

給定一個參數化的類型T,該語句t的變量t =零 纔有效,如果T是引用類型和t = 0將只 數值類型而不是結構工作。該解決方案是使用默認 關鍵字,這將返回null引用類型和零 爲數字值類型。對於結構,它將返回的 每個成員的結構初始化爲零或爲空,這取決於它們是否是 值或引用類型。對於可爲空的值類型,默認返回一個 System.Nullable,它與任何結構一樣被初始化。

+0

謝謝。這是否會破壞我的邏輯?經過一番思考,沒有。 –

1

這是因爲min的條件內進行分配。編譯器無法確定它是否會得到值,您應該使用default值初始化min。

4

min添加默認值:

T min = default(T); 

它的抱怨的原因是,編譯器不能驗證min將被分配一個值,它在return min;線使用之前。未分配的局部變量不能被引用,因此編譯器會產生一個錯誤。

-1

FYI這是我結束了

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

沒有,則無法測試一個變量是否分配,你總是會得到一個編譯錯誤。