Sunday, May 19, 2013

Capital Eye

What will the following line print out?

Console.WriteLine("i".ToUpper());

The answer is obvious: "It depends"

String.ToUpper as well as string.ToLower will use current thread culture, and in most cases it will print "I", but there is two cultures, where capital "i" is not "I", but "İ" - Turkish (tr) and Azeri Latin (az-Latn).

So never ever use ToUpper() and ToLower() in internal comparisons or serialization (I have found this while creating SQL queries, something like "... where id in [1]".ToUpper()), use ToLowerInvariant() and ToUpperInvariant() instead.

Compiled lambda issue



Never ever return the result of Expression<T>.Compile() method. If your compiled expression throws an exception, you will not get any info about the compiled lambda. For example, I have the NullReferenceException with following stack trace:


System.NullReferenceException: Object reference not set to an instance of an object.
   at lambda_method(Closure , BugDto )
   at System.Linq.Enumerable.WhereListIterator`1.MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Lookup`2.Create[TSource](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.GroupedEnumerable`3.GetEnumerator()
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
...

There is nothing that could help me to find the cause of exception, I don't know where the expression was compiled or even created.

The best you can do is to return Expression<T> itself and use IQueryable methods instead of IEnumerable.