6

以下のコードは有効です。

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
4

1 に答える 1

8

型推論を介してそれを行うことができます:

var func = BuildFunc((SomeThing item) => {
    return new { ... };
});

...

static Func<TSource, TResult> BuildFunc<TSource, TResult>(
    Func<TSource, TResult> function) {
    return function;
}

BuildFunc実際には何もしないことに注意してください-コンパイラにジェネリック型引数の型推論を行わせるために必要なメソッド呼び出しを提供するだけです-それは、基本的Func<,>に、あなたが興味のある情報を追加します-それはできない情報ですFunc<,>型引数を指定せずに、変数宣言の一部として指定する必要があります。

于 2012-05-09T20:44:14.450 に答える