程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 在含有null值的復雜類的集合(Collection)中取最大值,nullcollection

在含有null值的復雜類的集合(Collection)中取最大值,nullcollection

編輯:C#入門知識

在含有null值的復雜類的集合(Collection)中取最大值,nullcollection


在日常編程中,經常遇到要在一組復雜類的集合(Collection)中做比較、取最大值或最小值。

舉個最簡單的例子,我們要在一個如下結構的集合中選取包含最大值的元素:

public class Class<T> where T : struct
{
    public T? Value { get; set; }
}
var ints = new List<Class<int>>()
{
    new Class<int>() { Value = 2 },
    new Class<int>() { Value = 10 },
    new Class<int>() { Value = 5 },
    new Class<int>() { Value = 10 },
};

如果不使用.Net高級特性的做法通常是:

var max = new Class<int>() { Value = Int32.MinValue };
foreach (var i in ints)
{
    if (i.Value != null && i.Value > max.Value)
    {
        max = i;
    }
}

return max;

這樣的寫法,除了煩瑣無味以外,還有一個很明顯的Bug,雖然在上面這個例子中暴露不出來,但是假設集合沒有一個元素,或者組成如下:

var ints = new List<Class<int>>()
{
    new Class<int>() { Value = null },
    new Class<int>() { Value = null },
    new Class<int>() { Value = null },
};

此時此刻,我們想要返回的是包含null值的元素,而上述方法則帶給我們包含Int32最小值的元素,此元素並不在ints集合中!

 

你會想使用Linq框架的Max(),比如:

var max = ints.Max(i => i.Value);

但事實上這個方法只能返回元素的Value成員變量,也就是int?類型,所以這也不是我們想要的。

 

此時此刻,正確的方法可能是:

var max = ints.First(i => i.Value == ints.Max(j => j.Value));

 

但,這還是有機會拋異常的,假設集合如下

var ints = new List<Class<int>>()
{
    new Class<int>() { Value = null },
    new Class<int>() { Value = null },
    new Class<int>() { Value = null },
    null
};

在這個集合裡我們加了一個真正的null元素(而非包含null值的元素),ints.Max()就會拋NullReferenceException。

為了解決這個問題,我們可以將max聲明改寫為:

var max = ints.First(i => i.Value == ints.Max(j => { return j == null ? null : j.Value; }));

 

你可能已經注意到了,Max()方法中加了null值判斷,但First()方法中卻不需要。請先不要急於抱怨微軟設計的集合方法有行為不一致的現象。

至於為什麼,我將這個作業交給你,先自己在下面這個鏈接裡挖掘一下答案吧。:)

 

http://referencesource.microsoft.com/

(此網站是微軟早在兩年前建設好的用於方便軟件工程師查看.Net源代碼的網站)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved