List <string> .Contains(mystring)是否进行引用比较或值比较?</string>

时间:2009-08-12 04:33:44

标签: c# string

List.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);

由于

4 个答案:

答案 0 :(得分:6)

IList<T>使用Comparator<T>.Default进行比较,然后按String个对象的值进行比较。

如果您愿意,可以将项目移动到IDictionary<T, bool>或类似的项目,您可以在其中指定IComparator - 指定检查参考的项目。 (即使在那种情况下,你最好使用foreach循环)

如果你可以使用LINQ,你也可以在那里用参考比较创建一个语句。

答案 1 :(得分:4)

比较所有字符串是否按值重载。抱歉没有注意到你有一个SqlString,为什么不使用它的ToString()方法并添加?缩短的方法无法编译。

答案 2 :(得分:4)

来自List<T>.Contains的{​​{3}}

  

此方法使用确定相等性   默认的相等比较器   T EqualityComparer<T>.Default   列表中值的类型。

     

...   Default属性检查   类型T是否实现了   IEquatable<T>通用接口和   如果是,则返回EqualityComparer<T>   使用该实现。   否则它返回一个   EqualityComparer<T>使用   覆盖Object.Equals和。{   Object.GetHashCode提供T

查看反射器(并且通过最少惊讶的原则),String Equality具有值类型语义 - 因此如果它们具有相同的字符串则它们是相等的。 Equals(Object)IEquatable.Equals(T)都委托给String::EqualsHelper

答案 3 :(得分:2)

是的,您可以通过删除foreach来简化(就代码而言,而不是complexity *),但您的简化与原始功能不同。

简单的功能等价物是:

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(相同的命名空间)。它不会维持添加字符串的顺序,但它的Contains操作为O(1),而您当前的操作为O(n)