关于C#中的string.Intern

时间:2011-11-27 10:21:07

标签: c# .net winforms string

我需要在string.Intern值上致电string.IsInternedString的情况是什么情况?

我将网格用于分组行的方法:

    // get grouping value for DataGrid
    string GroupItemAccessor(object value)
    {
        COA coa = (COA)value;
        return string.IsInterned(coa.GroupName);
    }

如果我没有致电string.Intern,则结果有误,此网格应按GroupName的值进行分组。

String.Intern not used

如果使用string.Intern(如示例代码),则按预期工作。

String.Intern used

3 个答案:

答案 0 :(得分:4)

您得到不同结果的原因是您没有对字符串值进行分组,而是对字符串引用进行分组。字符串在分组时不被视为字符串,而是作为对象,因此只比较引用,而不是内容。

当您从数据库中读取值时,每个字符串将是一个单独的实例,即使它们具有相同的值。例如,前两个字符串“AAA”将是单独的对象,而不是对同一对象的引用。

如果无法在字符串值上创建网格组,则使用String.Intern是使字符串成为相同实例的一种方法,因此无论如何分组都可以正常工作。

但是,您可能希望使用自己的方法使字符串成为相同的实例,因为实习字符串意味着它们永远不会被垃圾回收。你可以使用这样的类:

public class LocalIntern {

  private Dictionary<string, string> _intern = new Dictionary<string, string>();

  public string Intern(string value) {
    if (_intern.ContainsKey(value)) {
      return _intern[value];
    } else {
      _intern.Add(value, value);
      return value;
    }
  }

}

当您再次填充网格时,您只需创建一个新的LocalIntern对象,并且可以对前一个中保存的字符串进行垃圾回收。

答案 1 :(得分:1)

猜测,SuperList可能会对分组进行身份检查(引用检查) - 如果确实如此,那么即使它们是相同的字符串,未被实现的字符串也会被视为不同。

在这种情况下,需要对字符串进行实习,以便控件正确分组。

答案 2 :(得分:1)

如果我猜,那么我会说网格使用参考平等。据我所知,只有文字字符串被实习。

因此,如果没有实际的coa.GroupName,两个相等的组名不是引用相等的,因此网格似乎不会以不同方式对待它们。