c# - 玩弄匿名类型

标签 c# c#-3.0 c#-4.0 anonymous-types

摘自 Jon Skeet 的精彩著作 C# In Depth, First Edition:

class Film
{
    public string Name { get; set; }
    public int Year { get; set; }

    public override string ToString()
    {
        return string.Format("Name={0}, Year={1}", Name, Year);
    }
}

var films = new List<Film>
{
    new Film {Name="Jaws", Year=1975},
    new Film {Name="Singing in the Rain", Year=1952},
    new Film {Name="Some Like It Hot", Year=1959},
    new Film {Name="The Wizard of Oz", Year=1939},
    new Film {Name="It's a Wonderful Life", Year=1946},
    new Film {Name="American Beauty", Year=1999},
    new Film {Name="High Fidelity", Year=2000},
    new Film {Name="The Usual Suspects", Year=1995}
};

Action<Film> print = film => { Console.WriteLine(film); };
films.ForEach(print);
films.FindAll(film => film.Year < 1960)
.ForEach(print);
films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name));
films.ForEach(print);

一段在上面列出的代码片段之后。

The first half of listing 9.4 involves just setting up the data. I would have used an anonymous type, but it’s relatively tricky to create a generic list from a collection of anonymous type instances. (You can do it by creating a generic method that takes an array and converts it to a list of the same type, then pass an implicitly typed array into that method. An extension method in .NET 3.5 called ToList provides this functionality too, but that would be cheating as we haven’t looked at extension methods yet!)

上面提供的代码片段是该段落所指的书的 list 9.4。

我的问题: 我正在手动尝试上一段中概述的技术(请看斜体字),但我不太明白他的意思。

我试过这样的东西,但我想这不是他的意思,因为它不起作用(我没想到它会起作用):

using System;
using System.Collections.Generic;

namespace ScratchPad
{

class Film
{
    public string Name { get; set; }
    public int Year { get; set; }

    public override string ToString()
    {
        return string.Format("Name = {0}\tYear = {1}", 
            Name, Year);
    }
}

class Program
{
    static void Main(string[] args)
    {
        ToList<Film>( new[]
        {
            new { Name = "North By Northwest", Year = 1959 },
            new { Name = "The Green Mile", Year = 1999},
            new { Name = "The Pursuit of Happyness", Year = 2006}
        }).ForEach( f => {Console.WriteLine(f);} );

        Console.ReadKey();
    }

    static List<T> ToList<T>(
        System.Collections.IEnumerable list)
    {
        var newList = new List<T>();

        foreach (var thing in list)
            if (thing is T)
                newList.Add((T)thing);

        return newList;

    }
}

注意:我知道 IEnumerable.ToList() 扩展方法并使用过很多次。我只想手动尝试该段落中概述的技术。

另外,我对在 Linq 之外使用匿名类型的场景很感兴趣,作为一种语法上的便利,下面给出了这样的场景之一。我始终可以在 C# 4 中使用 dynamic 并接受匿名类型作为参数并在知道我期望的情况下使用它。我希望我可以用 C# 3 做到这一点。如下所示:

using System;
using Microsoft.CSharp.RuntimeBinder;

namespace PlayWithAnonType
{
    class Program
    {
        static void Main(string[] args)
        {
            PrintThingy(new { Name = "The Secret", 
Genre = "Documentary", Year = 2006 });
            Console.ReadKey();
        }

    static void PrintWhatever(dynamic whatever)
    {
        // the anonymous type's ToString() will print
        Console.WriteLine(whatever);
    }

    static void PrintThingy(dynamic thingy)
    {
        try
        {
            // I know what the thingy is
            Console.WriteLine("Name = {0}\tGenre = {1}\tYear = {2}",
                thingy.Name, thingy.Genre, thingy.Year);
        }
        catch(RuntimeBinderException ex)
        {
#pragma warning disable 0168
            Console.WriteLine("By thingy, I really meant film. 
Sorry, I should've clarified.");
#pragma warning restore 0168
        }
    }
}

编辑 他们应该有一个名为 jon-skeet 的标签。

最佳答案

要点是,如果我们知道 ToList,我们就可以创建列表,而根本不需要我们自己的 Film 类型。这并不是说我们能够将匿名类型与 Film 类型混合使用。换句话说,我们可以这样做:

// The type of list will be List<T> where T is the anonymous type
var list = new[]
{
    new { Name = "North By Northwest", Year = 1959 },
    new { Name = "The Green Mile", Year = 1999},
    new { Name = "The Pursuit of Happyness", Year = 2006}
}.ToList();

list.ForEach(x => Console.WriteLine("{0} ({1})", x.Name, x.Year));

很高兴您喜欢第一版,顺便说一句 - 希望第二版发布不会太久 :)

关于c# - 玩弄匿名类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3256814/

相关文章:

c# - 如何设置两个单元格之间的空间

c# - 为什么按增量时间计算?

c# - XUnit HttpStatusCode 不包含 Should 的定义

c# - 对列表中的值进行分组并使用 C# 将输出转换为 JSON

SqlDbType.Time 溢出。值超出范围

c# - 在 C# 中重命名 Excel 工作表名称

c# - C#中的自赋值

c# - 在较长的运行过程中禁用 WPF 按钮,MVVM 方式

c# - 使用 Mono 的 mcs 使用 Tuple 编译代码

asp.net-mvc-2 - 发布网站后无法在 asp.net mvc2 中加载类型 'System.Web.Mvc.ViewPage<dynamic>'