I\'m trying to write an ExpressionVisitor to wrap around my LINQ-to-object expressions to automatically make their string comparisons case insensitive, just as they would be
I made a sample app from your code and it seems working:
public class Test
{
public string Name;
}
public class CaseInsensitiveExpressionVisitor : ExpressionVisitor
{
protected override Expression VisitMember(MemberExpression node)
{
if (insideContains)
{
if (node.Type == typeof (String))
{
var methodInfo = typeof (String).GetMethod("ToLower", new Type[] {});
var expression = Expression.Call(node, methodInfo);
return expression;
}
}
return base.VisitMember(node);
}
private Boolean insideContains = false;
protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (node.Method.Name == "Contains")
{
if (insideContains) throw new NotSupportedException();
insideContains = true;
var result = base.VisitMethodCall(node);
insideContains = false;
return result;
}
return base.VisitMethodCall(node);
}
}
class Program
{
static void Main(string[] args)
{
Expression <Func<Test, bool>> expr = (t) => t.Name.Contains("a");
var expr1 = (Expression<Func<Test, bool>>) new CaseInsensitiveExpressionVisitor().Visit(expr);
var test = new[] {new Test {Name = "A"}};
var length = test.Where(expr1.Compile()).ToArray().Length;
Debug.Assert(length == 1);
Debug.Assert(test.Where(expr.Compile()).ToArray().Length == 0);
}
}
you can create a extesion method like this:
public static class Extensions
{
public static bool InsensitiveEqual(this string val1, string val2)
{
return val1.Equals(val2, StringComparison.OrdinalIgnoreCase);
}
}
And then you can call like this:
string teste = "teste";
string teste2 = "TESTE";
bool NOTREAL = teste.Equals(teste2); //FALSE
bool REAL = teste.InsensitiveEqual(teste2); //true