Назначьте делегат функции, который возвращает анонимный тип переменной

Приведенный ниже код действителен:

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 { ... };
    };

, я получу ошибку «Невозможно присвоить лямбда-выражение локальной переменной с неявным типом». Это кажется странным ограничением компилятора; если я что-то не упустил, типы во втором примере столь же недвусмысленны, как и в первом: оба параметра типа хорошо определены.

Есть ли способ сделать это? Поскольку это анонимный тип, конечно, у меня нет никакого способа использовать тип для его явного назначения, поэтому, похоже, я застрял бы с созданием класса для выходного типа, если нет.

Обновление

Вскоре после моего веселого пути с ответом Джона Скита я обнаружил аналогичную дилемму, создающую экземпляры классов. Если это не очевидно, тот же трюк можно использовать для создания строго типизированных классов с использованием выведенных анонимных типов.

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
6
задан Jamie Treworgy 9 May 2012 в 21:32
поделиться