以下代码有效:
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>
,并且强烈键入函数中创建的匿名类型。真是太酷了。
我似乎无法做到的是找出一种方法将lambda表达式(而不是枚举)分配给隐式类型变量。即使编译器在上面的上下文中没有匿名类型的问题,如果我尝试(比如说)
var func = (SomeThing item)=> {
return new { ... };
};
我收到错误“无法将lambda表达式赋给隐式类型的局部变量”。这似乎是一个奇怪的编译限制;除非我遗漏了某些内容,否则第二个示例中的类型与第一个中的类型一样非模糊:两个类型参数都已明确定义。
有没有办法做到这一点?因为它是一个匿名类型,当然,我没有任何方法可以使用一个类型来明确地分配它,所以我似乎不会为输出类型创建一个类,如果不是。
更新
在与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
答案 0 :(得分:8)
您可以通过类型推断来实现:
var func = BuildFunc((SomeThing item) => {
return new { ... };
});
...
static Func<TSource, TResult> BuildFunc<TSource, TResult>(
Func<TSource, TResult> function) {
return function;
}
注意BuildFunc
并没有真正做任何事情 - 它只是提供了让编译器对Func<,>
的泛型类型参数进行类型推断所需的方法调用 - 它添加了你的信息基本上对Func<,>
感兴趣 - 这些信息不能作为变量声明的一部分指定,也不指定类型参数。