2009-08-12 72 views
3

List.Contains(mystring)做參考比較還是比較值? 例如,我有這樣的代碼:列表<String> .Contains(mystring)做參考比較還是比較值?

/// <summary> 
/// If the value isn't null or an empty string, 
/// and doesn't exist in the list, it adds it to the list 
/// </summary> 
static void AddToListIfNotEmpty(List<string> thelist, SqlString val) 
{ 
    string value = val.ToString().Trim(); 
    if (!string.IsNullOrEmpty(value)) 
    { 
    bool found = false; 
    foreach (string x in thelist) if (x == value) found = true; 
    if (!found) thelist.Add(value); 
    } 
} 

我能簡化的foreach及以下線路:

if (!thelist.Contains(value)) thelist.Add(value); 

感謝

回答

6

IList<T>使用Comparator<T>.Default進行比較,然後依次對比String對象的值。

如果你願意,你可以將你的物品移動到IDictionary<T, bool>或類似的地方,你可以指定你的IComparator - 指定一個檢查參考。 (即使在這種情況下,你最好使用foreach循環)

如果你可以使用LINQ,那麼你也可以在那裏創建一個語句,並帶有參考比較。

+0

通過參考進行比較是沒有意義的。 「SqlString」引用沒有辦法和列表中的「string」一樣嗎? – Thorarin 2009-08-12 05:10:42

+0

你是對的,我沒有注意到。這可能會使Equals方法也返回false。 在這種情況下,使用IDictionary技巧或LINQ是他的選擇, – 2009-08-12 05:19:05

+0

等等,我感到困惑了一下。他正在比較ToString()。Trim()值,而不是SqlString本身。 Equals可能工作,甚至可以在字符串被執行時進行參考比較。 – 2009-08-12 05:20:07

4

的所有字符串比較超載是按值。對不起,沒有注意到你有一個SqlString,爲什麼不使用它的ToString()方法並添加?你縮短的方法不會編譯。

+0

你是什麼意思,它不會編譯?它會編譯得很好。 'value'是'val'轉換爲'string'。 – Thorarin 2009-08-12 04:59:11

+0

我的中暑仍然在扼殺我,你是對的。 – 2009-08-12 05:09:11

4

List<T>.Contains

此方法MSDN確定使用 默認的相等比較 EqualityComparer<T>.Default爲T, 值的列表中的類型平等。

... 默認屬性檢查 類型T是否實現 IEquatable<T>通用接口和 如果這樣返回EqualityComparer<T> 使用該實現。 否則返回一個 EqualityComparer<T>使用的Object.EqualsObject.GetHashCode的 覆蓋由T提供。

查看反射器(以及最不驚奇的原則),字符串相等具有值類型語義 - 所以如果它們具有相同的字符串它們是相等的。無論Equals(Object)IEquatable.Equals(T)委託String::EqualsHelper

2

是的,你可以簡化(在代碼方面,不complexity *)通過移除在foreach,但你的簡化是不是功能上等同於原件。

的簡單求,功能等價物是:

static void AddToListIfNotEmpty(List<string> thelist, SqlString val) 
{ 
    string value = val.ToString().Trim(); 
    if (value != string.Empty && !thelist.Contains(value)) 
     thelist.Add(value); 
} 

請注意,您string.IsNullOrEmpty()將永遠不會遇到的字符串null參考。 編輯:在檢查後,我注意到SqlString.ToString()方法將NULL SqlString轉換爲字面值「Null」,我想這不是你想要的。你應該將其添加爲你的方法做的第一件事就是:

if (val.IsNull) 
    return; 

最後,回到我的複雜性意見:如果你正在處理大量的元素,你可能想看看HashSet代替使用List(相同的命名空間)。它不會保持添加字符串的順序,但是它的操作是,而您當前的操作是O(n)