Friday, June 16, 2017

dotnet core + bash

To update all packages in all projects:

find . -name "*.csproj" -exec sh -c "gawk 'match(\$0, /PackageReference Include=\"(.*)\" Version/, a){print a[1]}' {} | xargs -L1 dotnet add {} package" \;

To run all tests in all Tests projects:

find . -name "*Tests*.csproj" -execdir dotnet test --no-build {} \;

Tuesday, June 21, 2016

Nuget or not nuget

To switch all references from static dll to Nuget, use following snippet in Package Manager Console:

Get-Project -All | foreach-object {IF (Get-Content $_.FullName | Select-String "XXX") {Install-Package XXX -ProjectName $_.FullName}}

Monday, March 9, 2015

Group by order

Quite a common case - assume we have a collection of items and we want to iterate over it, but at first by items with some feature, then by items without such feature.

For instance, we have list of integers and want to iterate firstly all even numbers, then all odd numbers.

First approach is to group items by this feature and then iterate over group:

var ints = new[]{1,2,3,4,5};

var groups = ints.ToLookup(x=>x%2==0);

var result = groups[true].Concat(groups[false]);

foreach (var i in result){
    // ..
}



But there is a trick - a boolean value is comparable, false < true, so instead of creating lookups and concatenating we can simply order the collection by feature descendingly:

var ints = new[]{1,2,3,4,5};

var result = ints.OrderByDescending(x=>x%2==0);

foreach (var i in result){
    // ..
}


Thursday, November 21, 2013

Assert T

Here is some trick for getting over type erasure in Scala.


I want to create the following method that will expect an exception of particular type:

def assertT[T <: Throwable ](body: =>Unit) = {
  try {
    body
    assert(false)
  } catch {
    case e : T => assert(true)
  }
}

But due to type erasure, the case condition ( : T ) will be never checked. Scala compiler will warn you with "abstract type pattern T is unchecked since it is eliminated by erasure".

To fix this, you need a runtime class info and runtime class check:

def assertT[T <: Throwable : ClassTag](body: =>Unit) = {
  val clazz = implicitly[ClassTag[T]].runtimeClass
  try {
    body
    assert(false)
  } catch {
    case e if clazz.isInstance(e) => assert(true)
  }
}

where ClassTag is scala.reflect.ClassTag

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.

Monday, October 15, 2012

Queryable extensions

It is possible to extend a LINQ vocabulary with some custom methods that will be used later in query providers to build a custom query to outer source. Also, there is a little trick that allows using such extensions in Linq-to-objects expressions.

Here is a standard stub for an IQueryable method:


public static IQueryable<Tuple<int, TKey>> CountBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
{
    return source.Provider.CreateQuery<Tuple<int, TKey>>(
            Expression.Call(
              null,
              ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)),
              new[] { source.Expression, Expression.Quote(keySelector) }
                                                       ));
}

To add this methods for LINQ-to-Object you have to add the method for IEnumerable as well with same parameters (just replace Expression<Func<...>> with Func<...>) to the same type where IQueryable method is defined:


public static IEnumerable<Tuple<int,TKey>> CountBy<TSource,TKey>(this IEnumerable<TSource> source, Func<TSource,TKey> keySelector)
{
    return source.GroupBy(keySelector).Select(x => Tuple.Create(x.Count(), x.Key));
}