Saturday, December 25, 2010

Let.It.Be

Just another stupid question, bad for checking knowledge, but good enough to find out one's "tactical" architecture design capabilities.

It's not a secret that C# translates LINQ queries into chain of extension method calls. For instance, the following code snippet:

var entities = from e in list
               where e.Id > 10
               select e.Name;

will be transcribed as

var entities = list.Where(e=>e.Id > 10).Select(e=>e.Name);

But how is 'let' keyword transcribed? There is no .Let() method in LINQ. Could you suggest your solution?

Friday, November 19, 2010

Commutativity and LINQ

Yet another stupid questions. Imagine, you have defined a class:

class Entity{
 public int Id { get; set; }
 public int Priority { get; set; }
}

And also you have some sequence of Entity objects (i.e. IEnumerable entities). You need to group entities by its Id and select only entities with priority greater than 5.

As far as "and" is commutative and according to the task the following two blocks of code should return the same result


var group1 = entities.Where(e=>e.Priority > 5).GroupBy(e=>e.Id);
and
var group2 = entities.GroupBy(e=>e.Id).Select(g=>g.Where(e=>e.Priority > 5));

But this is wrong. There are two different sets of input data that will produce to different results (by two different reasons). Could you find them out?

Monday, November 1, 2010

Why IEnumerator<T> is IDisposable

Recently I've posted that IEnumerator<T> is IDisposable, but had not explained, why it is.

The explanation is rather simple - because of "yield return". Let's track this down.

Thursday, October 28, 2010

Static cache

Let's try to resolve a pretty regular case - some kind of key-value static cache. If there is no stored value for the specified key, the cache will call some external routine to get value and add it to the internal dictionary.

Here is a naive approach of the cache. It is straightforward enough.

public class Cache<TKey, TValue>
{
  Func<TKey, TValue> _resolver;
  Dictionary<TKey, TValue> _cache = new Dictionary<TKey, TValue>();

  public Cache(Func<TKey, TValue> resolver)
  {
    _resolver = resolver;
  }

  public TValue this[TKey key]
  {
    get
    {
       TValue value;
       if (!_cache.TryGetValue(key, out value))
       {
         value = _resolver(key);
         _cache.Add(key, value);
       }
       return value;
    }
  }
}

And also somewhere in a client code:
class ClientCode
{
  static Cache<TKey, TValue> _cache = new Cache<TKey, TValue>(Resolver);
}
Where Resolver is an user-defined function to get a value from the outer source.

Tuesday, October 12, 2010

Order zen

Pretty interesting question (and a good one for interview as well).

An Enumerable class contains two sets of methods: OrderBy() and ThenBy(). The first set sorts the elements of a sequence, second one performs a subsequent ordering of the elements in a sequence. If you have a sequence of names as {FirstName, LastName} and what to sort it by first name and then by last name you probably will not write as following:
var sorted = names.OrderBy(x=>x.FirstName).OrderBy(x=>x.LastName)

This is obviously wrong because you will firstly sort the sequence by FirstName and then resort it by LastName. To do the requested thing, you'll write:
var sorted = names.OrderBy(x=>x.FirstName).ThenBy(x=>x.LastName)

And here is the question - how ThenBy() is implemented (or how would you implement ThenBy() method)?

Monday, October 11, 2010

The vassal of my vassal is not my vassal

Just a thumb rule - avoid creating a PropertyExpression using

public static MemberExpression Expression.Property(Expression expression, MethodInfo property)

Instead prefer

public static MemberExpression Expression.Property(Expression expression, PropertyInfo property)

Tuesday, October 5, 2010

Interview

I would like to ask the following questions/tasks on a technical interview.
  1. Implement a singleton.
    Yes, kinda boring question. But I'll expect simple implementation, like follows:

    public class Singleton{
      private Singleton(){}
      public static Singleton Instance = new Singleton();
    }

    and nothing more. There is no words about laziness. Anything more complicated signals about over-engineering.
  2. Implement (I)Disposable pattern. And after it - When does a type need a finalizer?
    Second part is simple, first part is not good without explanation. In this case I'll wait for

    protected virtual void Dispose(bool isDisposing)

     
  3. ...to be continued