How to use CompareString() method

A

Andrus

I added reference to Microsoft.VisualBasic.dll to project.

Line

var r = Microsoft.VisualBasic.CompilerServices.CompareString("a", "b",
true)<1;

causes compile error:

The type or namespace name 'CompareString' does not exist in the namespace
'Microsoft.VisualBasic.CompilerServices' (are you missing an assembly
reference?)

According to MSDN doc this method must exist in this assembly.

How to use this method from C# ?
I need to create linq expression tree which calls this method.

Andrus.
 
J

Jeroen Mostert

Andrus said:
I added reference to Microsoft.VisualBasic.dll to project.

Line

var r = Microsoft.VisualBasic.CompilerServices.CompareString("a", "b",
true)<1;

causes compile error:

The type or namespace name 'CompareString' does not exist in the namespace
'Microsoft.VisualBasic.CompilerServices' (are you missing an assembly
reference?)

According to MSDN doc this method must exist in this assembly.
A method belongs to a class, not an assembly. It's a member of the Operators
class (which does reside in that assembly).
How to use this method from C# ?

You don't.
I need to create linq expression tree which calls this method.
I sincerely doubt that. There's a reason this method is flagged as "this API
supports the .NET Framework infrastructure and is not intended to be used
directly from your code."

I hesitate to ask why you think you need to create an expression tree that
uses Visual Basic internals in C#.
 
J

Jon Skeet [C# MVP]

Andrus said:
I added reference to Microsoft.VisualBasic.dll to project.

Line

var r = Microsoft.VisualBasic.CompilerServices.CompareString("a", "b",
true)<1;

causes compile error:

The type or namespace name 'CompareString' does not exist in the namespace
'Microsoft.VisualBasic.CompilerServices' (are you missing an assembly
reference?)

According to MSDN doc this method must exist in this assembly.

How to use this method from C# ?
I need to create linq expression tree which calls this method.

CompilerServices is a namespace - methods don't exist directly in
namespaces. CompareString is a method in the Operators class.

Why do you think you need to call it though? What's wrong with
String.CompareTo?
 
L

Larry Smith

I sincerely doubt that. There's a reason this method is flagged as "this
API supports the .NET Framework infrastructure and is not intended to be
used directly from your code."

That statement appears in many places in the docs but it's not always
trustworthy. It's part of a deeper problem with the .NET docs however which
are fundamentally very weak.
 
J

Jeroen Mostert

Larry said:
That statement appears in many places in the docs but it's not always
trustworthy.

I'm not sure what you mean. Are you telling me the framework developers flag
methods like this in error, that is, when something *is* intended to be used
directly from your code but they somehow haven't realized this themselves?
How do you argue with intention?
It's part of a deeper problem with the .NET docs however which are
fundamentally very weak.
Well, YMMV. I'll trot out the old adage that documentation is like sex: when
it's good it's very good, and when it's bad it's still better than nothing.

The problem with the infrastructure classes is not that they're tagged as
"not intended to be used" but that they're publicly exported in the first
place. Short of mashing lots of assemblies together or altering the way the
CLR handles visibility there's not much that can be done about that, though.
 
A

Andrus

Jona and Jeroen,
Why do you think you need to call it though? What's wrong with
String.CompareTo?

I need to generate dynamically sql select statement which compares strings:

SELECT COUNT(*)
FROM Customer
WHERE CustomerId < 'AIRBU';

I expect that

Db.Customers.Where( c =>
Microsoft.VisualBasic.CompilerServices.Operators.CompareString(
c.CustomerId, "AIRBU", false ) < 1 ).Count()

generates correct sql .

I'm not sure that String.CompareTo generates correct statement.

So I created following extension method based on Marc code samples:

public static IQueryable<T> LessThanOrEqual<T>(this IQueryable<T>
source, string property, object value)
{
ParameterExpression obj = Expression.Parameter(typeof(T), "x");
Expression val = Expression.Constant(value, typeof(string));
Expression prop = Expression.Property(obj, property);
Expression call = Expression.Call(
typeof(Microsoft.VisualBasic.CompilerServices.Operators).GetMethod("CompareString",
new[] { typeof(string), typeof(string), typeof(bool) }), prop,
val,
Expression.Constant(false, typeof(bool)));
BinaryExpression testExp = LambdaExpression.LessThan(call,
Expression.Constant(1, typeof(int))
);
return source.Where(Expression.Lambda<Func<T, bool>>(testExp,
obj));
}

Is this best solution ?

Andrus.
 
M

Marc Gravell

String.Compare should work just fine (assuming you get the sign the
right way, which always makes me have to stop and think...); example
using NWind:

int cnt = (from cust in ctx.Customers
where string.Compare(cust.CompanyName,"abc") < 0
select cust).Count();
/*
SELECT COUNT(*) AS [value]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[CompanyName] < @p0
*/

Marc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top