Wednesday, May 30, 2012

MakeGenericType

When does the following line of code could fail with "The number of generic arguments provided doesn't equal the arity of the generic type definition"?


var t = typeof (SomeGenericClass<,,>).MakeGenericType (typeof (int), typeof (int), typeof (int));

Where SomeGenericClass is defined as:

public class SomeGenericClass<TT1T2>
{
}

Answer (thx for Elena):

If SomeGenericClass is defined inside another generic type, its generic types arguments will consist of root type generic arguments and its own generic arguments. MakeGenricType will cut of all generic type arguments, so you have to provide types for base type definition too:


public class SomeRootClass<T3>
{
  public class SomeGenericClass<TT1T2>
  {
  }
...

var t = typeof (SomeGenericClass<,,>).MakeGenericType (typeof (T3), typeof (int), typeof (int), typeof (int));
...
}

Thursday, May 24, 2012

Reverse

Three tiny puzzles:
  1. Given the following interface:

    interface
     INode
    {
             INode Next { getset; }
             object Data { get; }
    }

    and a reference to root 
    INode root reverse a one-linked list. Do not use any additional collections, as arrays, lists or stacks.
    
    
  2. The same for this interface:

    interface INode
    {
             INode Next { get}
             object Data { getset; }
    }

  3. And the same for this:

    interface
     INode
    {
             INode Next { get}
             object Data { get; }
    }
First and second tasks are almost the same, the 3rd solution will be good for 1st and 2nd as well.

Thursday, May 17, 2012

Mix of Queryable and Enumerable

Some useful observation from Expressions world.

Let's imagine we have the following class:


public class Foo
{
 public int[] Items { getset; }
}



And we use it in some IQueryable request in a following manner:


var queryable = new[] { new Foo {Items = new[] { 1, 2, 3 }} }.AsQueryable();

var q = queryable.Select(x => x.Items.Select(y => y % 2 == 0));


Note, that Items implements IEnumerable only, so this query is represented as:
var q = Queryable.Select(queryable, x => Enumerable.Select<intbool>(x.Items, y => y % 2 == 0));

Enumerable.Select takes Func<,> as its second parameters and we're expecting that this functor will be transformed into some method. But in this case, functor inside a Select method will be translated in Expressions as well:



ParameterExpression CS1 = Expression.Parameter(typeof(Foo), "x");
ParameterExpression CS3 = Expression.Parameter(typeof (int), "y");

MemberExpression memberExpression = Expression.Property(CS1, items);
IQueryable<IEnumerable<bool>> q1 = queryable.Select(
  Expression.Lambda<Func<FooIEnumerable<bool>>>(
    Expression.Call(null, select, new Expression[]
      {
        memberExpression,
        Expression.Lambda<Func<intbool>>(
          Expression.Equal(
            Expression.Modulo(CS3,
                              Expression.Constant(2, typeof (int))),
            Expression.Constant(0, typeof (int))), new[] {CS3})
      }), new[] {CS1}));
The same could be used for creating your own Expressions - if you use methods that accept functors, do not compile them in place, just insert as Expression.Lambda.

Note, that if Items implement IQueryable rather than IEnumerable, the nested Lamba expression will be quoted:
 
public class Bar
{
 public IQueryable<int> Items { getset; }
}
var queryable = new[] { new Bar {Items = new[] { 1, 2, 3 }.AsQueryable()} }.AsQueryable();

var q = queryable.Select(x => x.Items.Select(y => y % 2 == 0));

ParameterExpression CS1 = Expression.Parameter(typeof(Foo), "x");
ParameterExpression CS3 = Expression.Parameter(typeof (int), "y");

MemberExpression memberExpression = Expression.Property(CS1, items);
IQueryable<IEnumerable<bool>> q1 = queryable.Select(
  Expression.Lambda<Func<FooIEnumerable<bool>>>(
    Expression.Call(null, select, new Expression[]
      {
        memberExpression, Expression.Quote(
        Expression.Lambda<Func<intbool>>(
          Expression.Equal(
            Expression.Modulo(CS3,
                              Expression.Constant(2, typeof (int))),
            Expression.Constant(0, typeof (int))), new[] {CS3})
        )
      }), new[] {CS1}));
And this is the only purpose for Expression.Quote method.

Tuesday, May 8, 2012

Two cool regex features


Unicode Character Properties

\p{spec}


where spec - various specs definitions like:

  • L - letter
  • Ll - lowercase letter
  • P - punctuation
  • Cyrillic - Cyrillic letter
  • InSpecials: U+FFF0..U+FFFF
... and much more.

Character Class Subtraction

Example:


[a-z-[aeiuo]]


A single letter is not a vowel.


Could be combined with Unicode character properties: 

non-English letters - [\p{L}-[\p{IsBasicLatin}]]


More examples here



Saturday, May 5, 2012

Delegate sum

Funny trick via http://confluence.jetbrains.net/display/ReSharper/Delegate+subtraction+has+unpredictable+semantics


Action a = () => Console.Write("A");
Action b = () => Console.Write("B");
Action c = () => Console.Write("C");
Action s = a + b + c + Console.WriteLine;
s(); //ABC
(s - a)(); //BC
(s - b)(); //AC
(s - c)(); //AB
(s - (a + b))(); //C
(s - (b + c))(); //A
(s - (a + c))(); //ABC

s = a + b + a;
(s - a)(); // AB