以下のコードは有効です。
IEnumerable<SomeThing> things = ...;
// map type SomeThing to a new anonymous type, resulting in a strongly typed
// sequence based on an anon type
var newList = things.Select(item =>
{
return new
{
ID = item.ID,
DateUpdatedOrCreated = ((DateTime)(item.DateUpdated ??
item.DateCreated)).ToShortDateString(),
Total = item.Part1 + item.Part2
};
});
newListは、Visual Studioに表示IEnumerable<'a>
され、関数で作成された匿名型で強く型付けされます。かっこいいな。
私ができないように見えるのは、ラムダ式だけを(列挙ではなく)暗黙的に型指定された変数に割り当てる方法を見つけることです。上記のコンテキストでは、コンパイラは匿名型に問題はありませんが、(たとえば)
var func = (SomeThing item)=> {
return new { ... };
};
「暗黙的に型指定されたローカル変数にラムダ式を割り当てることができません」というエラーが表示されます。これは奇妙なコンパイラの制限のようです。何かが足りない場合を除いて、2番目の例では、最初の例と同じように型が明確になっています。両方の型パラメーターが明確に定義されています。
これを行う方法はありますか?もちろん、匿名型なので、型を使って明示的に割り当てる方法がないので、そうでない場合は、出力型のクラスを作成するのに行き詰まっているようです。
アップデート
Jon Skeetの答えを使って陽気な道を進んだ直後に、クラスをインスタンス化する同様のジレンマを見つけました。明らかでない場合は、同じトリックを使用して、推測された匿名型を使用して強い型のクラスを作成できます。
class Processor<T,U>
{
public Processor(Func<T,U> func) {
}
}
// func is a delegate with anon return type created using method in answer below
var instance = new Processor(func); // does not compile! Requires type arguments!
直接作成することはできませんが、以下のトリックとほぼ同じ方法で作成できます。
public static Processor<T,U> Create<T,U>(Func<T,U> func) {
return new Processor<T,U>(func);
}
var instance = Processor.Create(func); // all good