I like this simple tool:
public static class Klass
{
public static Klass<T> Of<T>(){ return Klass<T>.instance; }
}
public class Klass<T>
{
public static Klass<T> instance = null;
}
and now you can:
public K Process<T,K>(Klass<T> t, IEnumerable<K> items)
{
....
}
var aKey = Process(Klass.Of<string>(), mySetOfItems);
// aKey will be autotyped to a string
but note that this required the addition of an unused parameter to the Process method. This parameter is used solely just to resolve the missing type. This is why the 'instance' is always null. The value is not important, all that counts is that this null is of type Klass.
However, note that this 100%ly saves you from using explicit type parameters like in Process<string, ....>
because you do not need to explitely pass the <string>
type parameter. So, all type parameters are bound to arguments and this allows the copiler to automatically resolve the anonymous types, including the IEnumerable's item.
Edit: I've just remembered about one more thing, albeit more complicated and tricky. Anonymous types are fully ducktyped. This means that one anonymous type with "string Key, int Value" is absolutely of the same class as a second anonymous type created elsewhere which also is "string Key, int Value". This allows you to create a small helper method described here CastByExample.
Normally, you cannot "specify" the anonymous type, because, well, it is unnamed, and you cannot write the name of it. But, thanks to the ducktyping, this precious article shows how can you provide a never-executed lambda that returns a "sample" anonymous object just for the purpose of intercepting the anonymous-type that it defines, so that type can be passed down the chain of expressions. Very cornercase'y, but interesting thing!