[英]Base type of Anonymous Array that is Enumerable
我有以下方法,效果很好。
//private static IEnumerable<object> movieSequence;
private static void DeferredExecution()
{
var movieSequence = new[] {
new {Name="Harry potter", Genre="Action/Thrill", ReleasedYear=2011, Price=24.0},
new {Name="Tooth fairy", Genre="Family", ReleasedYear=2010, Price=20.5},
new {Name="How to train your dragon", Genre="Family", ReleasedYear=2010, Price=20.5}
};
double priceMultiplier = 0.5;
var newPriceList = movieSequence.Select(movie => new
{
Name = movie.Name,
Genre = movie.Genre,
ReleasedDate = movie.ReleasedYear,
Price = movie.Price * priceMultiplier
});
foreach (var movie in newPriceList)
{
Console.WriteLine("{0} ({1}) costs ${2}", movie.Name, movie.ReleasedDate, movie.Price);
}
}
但是,我想扩展movieSequence的范围。 由于它是匿名数组类型,因此无法确定其类型。
IEnumerable 不起作用,因为无法指定 T,代替 T 的对象无法带来电影名称、电影类型等。
非通用 IEnumerable 没有 Select 扩展名。
IList、ICollection(数组的父级)等没有 Select 扩展名。 显然“var”不是类级别的选项。
可能的类型是什么?
这是一个坏主意。 虽然可以使用IEnumerable<object>
和dynamic
的组合来扩展匿名类型的枚举范围,但这确实是一种糟糕的设计。
只需为此创建一个专用类,您就可以以强类型方式传递它。 以后阅读、维护和重构会容易得多。
我认为(还没有尝试过)你可以使用dynamic[]
+ IEnumerable<dynamic>
而不是[]
+ IEnumerable<object>
,但我会建议不要这样做。 为您的对象实际构建一个类型要好得多。
最简单的事情就是简单地提取一个类型:
class Movie
{
string Name {get;set;}
string Genre {get;set;}
int ReleasedYear {get;set;}
decimal Price {get;set;}
}
并将new {...}
替换为new Movie{...}
。 您可以保留自动键入的数组。
我认为最好的选择是用 Movie 制作一个具体的类型。 您甚至可以将价格行为移到该类中。 有一些工具可以帮助您提取类型。 (我知道 Resharper 可以。对于像这样的小型简单类型,我可能会自己使用自动属性快速输入它,并在需要时从那里进行重构。
public class Movie
{
public string Name { get; set; }
public string Genre { get; set; }
public int ReleasedYear { get; set; }
public double Price { get; set; }
public Movie ChangePrice( double multiplier )
{
return new Movie()
{
Name = Name,
Genre = Genre,
ReleasedYear = ReleasedYear,
Price = Price * multiplier
};
}
}
你的延迟执行方法最终会是这样的:
static IEnumerable<Movie> NewPriceList()
{
var movieSequence = new[]
{
new Movie("Harry potter", "Action/Thrill", 2011, 24.0),
new Movie("Tooth fairy", "Family", 2010, 20.5),
new Movie("How to train your dragon", "Family", 2010, 20.5)
};
double priceMultiplier = 0.5;
return movieSequence.Select(movie => movie.ChangePrice(priceMultiplier));
}
另一种选择是返回一个IEnumerable<dynamic>
,但除非您确实需要将此类型视为动态类型,否则我不会这样做。 在我看来,绕过匿名类型的范围问题并不是动态的合理使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.