C#4.0隐式类型动态对象

Jos*_*ell 5 c# linq dynamic anonymous-types .net-4.0

数据文件:(Data.txt)行代表width height

5
6 9
7 2
4 4
Run Code Online (Sandbox Code Playgroud)

C#代码:

var list = new List<dynamic>();
using (var sr = new StreamReader("Data.txt", Encoding.UTF8))
{
    list = sr.ReadToEnd().Split('\n').Select(r =>
    {
        var split = r.Split(' ');
        var len = split.Length;
        return new {
            w = len > 0 ? int.Parse(split[0].Trim()) : 0,
            h = len > 1 ? int.Parse(split[1].Trim()) : 0 
        } as dynamic;
    }).ToList();
}
int Area = list.Sum(r => r.h * r.w);
Run Code Online (Sandbox Code Playgroud)

该示例按原样工作.我不得不做一些不受欢迎的事情才能让它发挥作用.

首先,我必须声明列表以避免使用范围 - 因为我没有类型化维度对象,所以我将类型设置为dynamic(var list = new List<dynamic>()).

不受欢迎的部分是将匿名对象转换为dynamic(as dynamic).否则我明白了

无法隐式转换 System.Collections.Generic.List<AnonymousType#1>System.Collections.Generic.List<dynamic>

为什么我会收到此错误?我知道动态可以保持匿名类型,这是ToList()扩展和动态的问题吗?

我需要能够访问using语句之外的匿名列表项,如计算区域的最后一行.


解决方案: 我接受了dtb的回答.它避免了使用使用声明和动态.谢谢大家的投入!

var list = 
    (from line in File.ReadLines("Data.txt")
    let parts = line.Split(' ')
    let width = int.Parse(parts[0])
    let height = parts.Length > 1 ? int.Parse(parts[1]) : 0
    select new { width, height }).ToList();
Run Code Online (Sandbox Code Playgroud)

dtb*_*dtb 6

您可以使用File.ReadLines来避免StreamReader.

IEnumerable<dynamic> query =
    from line in File.ReadLines("Data.txt")
    let parts = line.Split(' ')
    let width = int.Parse(parts[0])
    let height = parts.Length > 1 ? int.Parse(parts[1]) : 0
    select new { width, height } as dynamic;

List<dynamic> list = query.ToList();

int area = list.Sum(t => t.width * t.height);
Run Code Online (Sandbox Code Playgroud)

但是,正如其他人所指出的那样,使用动态在这里并不合适.如果您仅在方法中使用查询,则匿名实例就足够了.如果要在方法外使用查询结果,请创建一个小结构或类,或使用Tuple <T1,T2>.