0

我想写

CompareInfo myCompIntl = CompareInfo.GetCompareInfo( "es-ES" );
var SharedYomi = from ObjA in ClassListA
                 join ObjB in ClassListB
                 where CompareInfo.Compare(ObjA.Name, ObjB.Name) == 0
                 select new {stringA = stringA, string = string};

Linq 强迫我写 join with equals。我无法通过布尔评估。我怎样才能做到这一点?

4

1 回答 1

0

您不能使用 LINQ lambda 查询语法来编写它。join关键字要求您准确指定使用关键字比较的两个属性,因为这映射到使用默认比较器比较键equals的第一个重载。Join

但是,Join接受一个IEqualityComparer可能对您有用的重载,您只需要使用方法查询语法。

由于您听起来对方法语法不熟悉,因此这里有一篇来自 MSDN 的不错的入门文章:

http://msdn.microsoft.com/en-us/library/vstudio/bb397947.aspx

但是,基本上,您认为“LINQ”的语法只是引用 LINQ 扩展的一种方式,实际上只是围绕IEnumerable实现 LINQ 的扩展方法的语法糖。因此,例如,查询:

from x in y where x.IsActive orderby x.Name select x

它基本相同

y.Where(x => x.IsActive).OrderBy(x => x.Name).Select(x => x);

在大多数情况下,每个查询子句都映射到特定IEnumerable方法的特定重载,但这些方法还有许多其他重载,它们采用不同数量和类型的参数。

这些Join方法有点复杂,因为它们将两个序列作为输入,并让您使用表达式组合它们的各个元素,但想法完全相同。典型的联接如下所示:

from x in y
join a in b on x.Id equals a.ParentId
select new { x.Id, x.Name, a.Date }

变成

y.Join(
  b, 
  x => x.Id, 
  a => a.ParentId, 
  (x, a) => new { x.Id, x.Name, a.Date });

这将加入a.ParentIdx.Id使用其数据类型(int、string 等)的默认比较。编译器直接将查询语法翻译成方法语法,因此两者的行为完全相同。(挑剔我自己的答案:从技术上讲,这些方法在Enumerable类上,所以你真的在调用Enumerable.Join. 但由于它们是作为扩展方法实现的,你可以用任何一种方式调用它们,编译器会弄清楚。)

在您的情况下,您需要传递不同的比较方法,以便您可以string.Compare使用显式编码进行调用。的另一个重载Join允许您提供一个实现IEqualityComparer<T>来使用而不是默认值。这将要求您IEqualityComparer<string>在一个单独的类中实现,因为没有简单的方法来创建匿名接口实现(可能是我从 Java 中错过的唯一功能)。对于你的例子,你想要这样的东西:

public class ComparerWithEncoding : IEqualityComparer<string>
{
  private CompareInfo compareInfo
  public ComparerWithEncoding ( string encoding )
  {
    this.compareInfo = CompareInfo.GetCompareInfo(encoding);
  }

  public bool Equals ( string a, string b )
  {
    return CompareInfo.Compare(a, b) == 0
  }

  public int GetHashCode(string a)
  {
    return a.GetHashCode();
  }
}

classListA.Join(
  ClassListB,
  ObjA => ObjA.Name,
  ObjB => ObjB.Name,
  (ObjA, ObjB) => new { stringA = ObjA.Foo, stringB = ObjB.Bar },
  new ComparerWithEncoding("es-ES"));
于 2013-08-14T14:06:51.443 回答