Reputation: 26756
I'm actually trying to answer this question but as that's very involved and unlikely to get a good response quickly, I'm going to try and work out the implementation myself. The fundamental problem seems to be that the C# example I was following doesn't translate directly to VB.
When examining a String comparison BinaryExpression
in a lambda, VB reports the Expression.Method.DeclaringType
to be Microsoft.VisualBasic.CompilerServices.Operators
with a method name of CompareString
. This is clearly VB-specific.
The Expression is just comparing x.Content_Type <> ""
and calling ToString on it returns {(CompareString(x.Content_Type, "", False) != 0)}
- which seems pretty logical (CompareString docs here).
Can someone explain to me how (or even better, why) VB and C# handle string comparisons differently.
I think if I can get an answer to that, I should be able to work out a solution to the other problem.
Edit:
To clarify, I'm implementing a custom LINQ provider which is examining the following Where
call:
Query.Where(function(x) x.Content_Type <> "")
or the C# equivalent...
query.Where(x=>x.Content_Type!="");
As far as I'm aware, the 2 should be functionally identical
Upvotes: 4
Views: 5410
Reputation: 63340
Decompiling CompareString
gives
public static int CompareString(string Left, string Right, bool TextCompare)
{
if (Left == Right)
return 0;
if (Left == null)
return Right.Length == 0 ? 0 : -1;
else if (Right == null)
{
return Left.Length == 0 ? 0 : 1;
}
else
{
int num = !TextCompare
? string.CompareOrdinal(Left, Right)
: Utils.GetCultureInfo().CompareInfo
.Compare(Left, Right, CompareOptions.IgnoreCase
| CompareOptions.IgnoreKanaType
| CompareOptions.IgnoreWidth);
if (num == 0)
return 0;
return num > 0 ? 1 : -1;
}
}
from which can be seen that there's custom logic around null
("Nothing
in Visual Basic", as the refrain goes) handling, and more importantly, a mode-switching parameter TextCompare
, which takes its value from the Option Compare
setting in effect.
Perhaps explicitly using a method on string
, rather than a comparison operator, would help you out.
As to the 'why', well, VB (classic) was always culturally a more "do the sensible thing" language, as opposed to the "do exactly what I tell you, nothing more, nothing less" philosophy of the C++ / Win32 world. VB.NET and C# are closer, but still differences like this remain.
Upvotes: 6
Reputation: 941218
VB.NET inherited the Option Compare
statement from previous versions of Visual Basic. To make that work, all string comparison expressions in VB.NET are translated to a helper function that can find out what the selected Option Compare value was in the specific source code file in which the statement was written.
The Operators.CompareString(string, string, bool) method is that helper function. The last argument is named "TextCompare", the VB.NET compiler automatically passes True if Option Compare Text is in effect, False if Option Compare Binary is in effect.
C# doesn't have anything like that.
Upvotes: 11