4

我有一个问题应该是微不足道的,但我找不到任何优雅的答案。

我有一个 a 的实例,IList<string>我想得到一个逗号分隔的所有不同(不区分大小写)值的字符串。

我以为我会为此使用string.Joinhelper,因为它有一个很好的重载,可以接受IEnumerator<string>as 参数。不幸的是,我发现遇到了一个障碍:spring4d 重新定义IEnumerator<T>了,当然,在任何地方都使用它自己的类型。

结果是以下代码无法编译:

var
  distinct: system.IEnumerator<string>;
begin
  result := inherited GetToken;
  if assigned(result) then
  begin
    if not Modules.Contains(STR_DID_SESSION_MODULE) then
      Modules.Add(STR_DID_SESSION_MODULE); 
    distinct := TDistinctIterator<string>.Create(Modules, TIStringComparer.Ordinal);
    result.CustomClaims.Items[STR_CLAIM_CUSTOM_MODULES] := string.Join(',', distinct);
  end;
end;

分配distinct失败E2010 Incompatible types: 'System.IEnumerator<System.string>' and 'Spring.Collections.Extensions.TDistinctIterator<System.string>'

或者,如果我从 distinct 中删除命名空间,则调用string.Join失败。

知道我应该怎么做吗?缺少手动遍历迭代并手动执行连接?

4

1 回答 1

5

自己写(FWIW我更喜欢相反的参数顺序,但自从签名以来我一直这样TStringHelper.Join):

function StringJoin(const separator: string; const values: Spring.Collections.IEnumerable<string>): string; overload;
var
  e: Spring.Collections.IEnumerator<string>;
begin
  e := values.GetEnumerator;
  if not e.MoveNext then
    Exit('');
  Result := e.Current;
  while e.MoveNext do
    Result := Result + separator + e.Current;
end;

您也可以编写更短的代码(无需手动创建迭代器Spring.Collections.Extensions):

StringJoin(',', TEnumerable.Distinct<string>(Modules, TStringComparer.OrdinalIgnoreCase))

现在,如果我们有接口助手,我们可以轻松地为IEnumerable<string>和添加ToDelimitedString或类似的东西编写一个助手。

于 2017-11-27T13:34:34.540 回答