【问题标题】:String Comparisons using LINQ Expressions and String.Format使用 LINQ 表达式和 String.Format 进行字符串比较
【发布时间】:2012-07-12 16:04:41
【问题描述】:

我正在使用 LINQ 表达式动态搜索集合中的值,我遇到了一个奇怪的问题,该问题似乎是由搜索 String.Format() 操作结果的字符串引起的。

这是我正在尝试做的简化版本,因为在实践中我实际上并不知道我正在搜索什么类型的值,所以我必须将所有内容都视为Object

Dim stringToFind As String = "Some Special Value"

' Create a collection of 10 strings, one of which being the string to find '
Dim myStrings As New List(Of Object)
For i As Integer = 0 To 9
    If (i = 3) Then
        myStrings.Add(String.Format(stringToFind))
    Else
        myStrings.Add("Boring Plain Old Value")
    End If
Next

' Create the predicate for <Function(x) x = stringToFind> '
Dim left = Expression.Parameter(GetType(Object), "x")
Dim right = Expression.Constant(stringToFind)
Dim eq = Expression.Equal(left, right)
Dim predicate = Expression.Lambda(Of Func(Of Object, Boolean))(eq, left).Compile()

' Compare the results '
Dim standardResults = myStrings.Where(Function(x) x = stringToFind)
Dim expressionResults = myStrings.Where(predicate)

' Expected Output:'
' Standard Method: 1 '
' LINQ Expressions: 1 '
Console.WriteLine(String.Format("Standard Method: {0}", standardResults.Count()))
Console.WriteLine(String.Format("LINQ Expressions: {0}", expressionResults.Count()))
Console.ReadLine()

这里发生的情况是标准方法正确返回 1 个结果,而 LINQ 表达式方法返回 0。但是,如果不使用 String.Format() (myStrings.Add(stringToFind)) 将特殊值添加到集合中,则表达式也返回正确的结果。

String.Format() 是否会更改字符串的编码,或者会影响如何为字符串值创建常量表达式?有没有另一种方法可以让我使用 LINQ 表达式比较两个值来绕过这个限制?

【问题讨论】:

  • 每个字符串都是一样的。它不会被 String.Format() 神奇地改变。

标签: .net string linq string-comparison linq-expressions


【解决方案1】:

VB.NET 相等运算符不进行引用比较。粗略地说,它使用object.Equals 方法(相对于object.ReferenceEquals)。表达式树使用对象引用相等性。

使用string.Format 并没有做任何特别的事情。 (没有“特殊”字符串)。

【讨论】:

  • 也许不是,但 String.Format(stringToFind) 和 stringToFind 之间显然必须有一些区别,否则两种情况都会产生相同的结果。您是说 String.Format(stringToFind) 生成一个新的字符串实例,以便 ExpressionEquals 的计算结果为 false?
  • @MikeC,没错。这个特定字符串引用的新实例比较为假。
  • 谢谢,我能够对 Expression.Call 使用重载来指定使用 Object.Equals 方法而不是 Object.ReferenceEquals - Expression.Equal(left, right, False, GetType(Object)。 GetMethod("Equals", {GetType(Object), GetType(Object)})) 就成功了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-01
相关资源
最近更新 更多