我想写
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强迫我用equals写连接。我无法通过布尔评估。 我怎么能这样做?
答案 0 :(得分:0)
您不能使用LINQ lambda查询语法编写它。 join
关键字要求您准确指定使用equals
关键字进行比较的两个属性,因为这会映射到Join
的第一个重载,它使用默认比较器来比较键。
但是,Join
的重载会接受可能适合您的IEqualityComparer
,您只需要使用方法查询语法。
由于您听起来不熟悉方法语法,因此以下是MSDN的一篇好文章:
http://msdn.microsoft.com/en-us/library/vstudio/bb397947.aspx
但是,基本上,你认为是“LINQ”的语法只是引用LINQ扩展的一种方式,而实际上只是围绕实现LINQ的IEnumerable
扩展方法的语法糖。因此,例如,查询:
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 });
这将使用其数据类型(int,string等)的默认比较来加入a.ParentId
和x.Id
。编译器直接将查询语法转换为方法语法,因此两者的行为完全相同。 (挑剔我自己的答案:从技术上讲,这些方法都在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"));