2017-05-17 48 views
2

我想下面的代码来创建一个不区分大小写的IList创建和使用不敏感的IList 的情况下: 如何Spring4d

procedure TForm1.ListButtonClick(Sender: TObject); 
var 
    MyList: IList<string>; 
begin 
    MyList := TCollections.CreateList<string>(TStringComparer.OrdinalIgnoreCase()); 
    MyList.AddRange(['AAA', 'BBB', 'CCC']); 
    Memo1.Lines.Add(MyList.IndexOf('aaa').ToString); 
end; 

然而,呼叫的IndexOf总是返回-1。这应该工作吗?任何建议感激。

更新:它看起来像被用于排序的比较器,但不适合的IndexOf。一个单独的“EqualityComparer”用于IndexOf,所以问题变成了如何改变它?

UPDATE2:我只是想补充到约翰的回答,该列表就可以像这样创建:

MyCIList := TCaseInsensitiveList<string>.Create(
    TStringComparer.OrdinalIgnoreCase(), 
    TStringComparer.OrdinalIgnoreCase()); 

回答

1

这个问题在Spring4D修补程序1.2.1得到解决。随着更改,下面的代码按预期工作。

procedure TForm1.ListButtonClick(Sender: TObject); 
var 
    MyList: IList<string>; 
begin 
    MyList := TCollections.CreateList<string>(TStringComparer.OrdinalIgnoreCase()); 
    MyList.AddRange(['AAA', 'BBB', 'CCC']); 
    Memo1.Lines.Add(MyList.IndexOf('aaa').ToString); // Correctly returns 0. 
end; 
+0

太好了,我只是在需要这个功能。找不到你提到的spring4d spring4d 1.2.1修补程序,但是2017年1月3日发布的spring 1.2已经工作了。 –

1

的IndexOf的代码如下所示:

function TList<T>.IndexOf(const item: T; index, count: Integer): Integer; 
begin 
    Result := TArray.IndexOf<T>(fItems, item, index, count, EqualityComparer); 
end; 

的EqualityComparer是调用GetEqualityComparer的属性如下所示:

protected 
    class function GetEqualityComparer: IEqualityComparer<T>; static; 

This static表示该方法不能在子类中被重写。

你需要编辑春源并进行以下修改:

Spring.Collections.Base

103: TEnumerableBase<T> = class abstract(TEnumerableBase, IEnumerable<T>) 
106: protected 
108: class var fEqualityComparer: IEqualityComparer<T>; 
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
//Move this line from private to the protected section. 
....... 

                   ^^^^^^^^ 

现在你可以创建自己的TCaseInsensitiveList像这样:

type 
    TCaseInsensitiveList<T> = class(Spring.Collections.TList<T>) 
    constructor Create(const Comparer: IComparer<T>; 
         const EqualityComparer: IEqualityComparer<T>); 
    end; 
    ..... 
constructor TCaseInsensitiveList<T>.Create(
      const Comparer: IComparer<T>; 
      const EqualityComparer: IEqualityComparer<T>); 
begin 
    inherited Create(Comparer); 
    Self.fEqualityComparer:= EqualityComparer; 
end; 

或者你也可以声明基本GetEqualityComparer类函数是虚拟和overri德在小孩班。

还有就是要使得GetEqualityComparer虚拟的,这就是为什么我选择做保护的基础类变量成本。

+0

很不错的!小注意到类(部分应该是类(Spring.Collections.Lists.TList )。我发现你在Spring4D问题跟踪器中提到了这个问题...谢谢! – MarkF