当前位置:  开发笔记 > 编程语言 > 正文

方法和匿名类型

如何解决《方法和匿名类型》经验,为你挑选了3个好方法。

我知道你不能从方法中返回匿名类型,但我想知道Select扩展方法如何返回匿名类型.它只是一个编译技巧吗?

编辑

假设L是一个列表.这是如何运作的?

L.Select(s => new { Name = s })

返回类型是IEnumerable <'a>其中'a = new {String Name}



1> Jon Skeet..:

嗯,这是泛型方法类型参数的正常类型推断.例如:

List x = new List();

// The compiler converts this:
x.Select(y => y.Length);

// Into this, using type inference:
Enumerable.Select(x, y => y.Length);

如果x是某个匿名类型的列表,或者lambda表达式的推断返回类型是匿名类型,则情况也是如此.不要忘记即使你不能明确说明使用匿名类型的变量的类型,它仍然一个确定的类型,编译器已知.



2> Mark Bracket..:

该类型实际上是由调用者定义,因此它在调用函数的范围内 - 整齐地避免了"返回"匿名类型的问题.

这是通过通用类型推断实现的.Select的签名是Select(IEnumerable, Func.的IEnumerable是,很明显,源集合.该Func转换函数是在编译器可以使用类型推理来声明匿名类型.

换句话说,为了传递FuncSelect你,你 - 调用者 - 必须定义TResult.这意味着Select不会返回由它定义的匿名类型 - 而是由您自己返回.

要模拟这个,你只需让调用者来定义类型:

TResult ReturnAnonymousType(Func f) {
   return f();
}

Console.WriteLine(ReturnAnonymousType(
   () => return new { Text = "Hello World!" } // type defined here, before calling 
);



3> Marc Gravell..:

来自评论:"那么我将如何实施类似的方法"

这里你需要的是任何通用方法:

public List Foo(T template) { // doesn't actually use "template"
    return new List();  // just an example
}

然后你可以:

var list = Foo(new {Bar=1});

编译器提供via泛型类型推断.

有点厚脸皮,但你甚至可以毫不费力地创建一个anon类型的实例:

public List Foo(Func func) { // doesn't actually use "func"
    return new List(); // just an example
}

var list = Foo(() => new {Bar = 1});

同样,编译器通过lambda的返回值提供.

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有