来自 Jon Skeet 的精彩书籍 C#深度剖析,第一版:
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);
上面的代码片段后面跟着一个段落。
列表9.4的前半部分只涉及数据的设置。我本来想使用匿名类型,但是从匿名类型实例的集合创建通用列表相对棘手。(您可以通过创建一个通用方法,将数组转换为同一类型的列表,然后将隐式类型的数组传递给该方法来完成它。.NET 3.5中的扩展方法ToList也提供了这个功能,但那样做是作弊的,因为我们还没有看过扩展方法!)
而上面提供的代码片段是书中第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的标签。