我有以下类来存储一些静态数据。我还有几种使用LINQ过滤数据的方法。像这样:
static class Data {
// ...
static public Weapon[] weapons = new Weapon[] {
// ...
}
static public GetUnlockedWeapons() {
Data.weapons.Where( a => a.unlocked ).ToArray();
}
static public GetWeaponsType(string type) {
Data.weapons.Where( a => a.type == type ).ToArray();
}
// ...
}
但现在我看到这种方式不是很灵活。当我构建更多过滤器时,将它们组合起来非常困难和/或冗长。
我来自Ruby on Rails开发,其中ActiveRecord具有可链接的scopes
。
我想知道我是否有某种方式可以chain
我的过滤器,方式与此相似:
weapons = Data.weapons.unlocked().type("sword").andMore().andEvenMore();
答案 0 :(得分:3)
是的,你可以这样做:
static class Data {
// ...
static public Weapon[] weapons = new Weapon[] {
// ...
}
public static IEnumerable<Weapon> GetUnlockedWeapons(this IEnumerable<Weapon> weapons) {
return weapons.Where( a => a.unlocked );
}
public static IEnumerable<Weapon> GetWeaponsType(this IEnumerable<Weapon> weapons, string type) {
return weapons.Where( a => a.type == type );
}
// ...
}
使用它:
var weapons = Data.weapons.GetUnlockedWeapons().GetWeaponsType("pistol").AndMore().ToList();
没有必要返回一个数组,因为它可能会链接它。将集合的具体化保留给调用者(在这种情况下,我们使用ToList
)
答案 1 :(得分:2)
如何将过滤器定义为extension methods
到IEnumerable<Weapon>
类型:
public static class Data
{
public Weapon[] GetUnlockedWeapons(this IEnumerable<Weapon> weapons)
{
return weapons.Where( a => a.unlocked ).ToArray();
}
public static Weapon[] GetWeaponsType(this IEnumerable<Weapon> weapons, string type)
{
return weapons.Where( a => a.type == type ).ToArray();
}
}
现在假设您有一个武器列表,您可以将这些过滤器应用于它:
Weapon[] weapons = new Weapon[]
{
// ...
};
weapons = weapons.unlocked().type("sword").andMore().andEvenMore();
或者,您可以定义使用所谓的流畅接口的API:
public class Data
{
public Data(Weapon[] weapons)
{
this.Weapons = weapons;
}
public Weapon[] weapons { get; private set; }
public Data GetUnlockedWeapons()
{
return new Data(this.Weapons.Where( a => a.unlocked ).ToArray());
}
public Data GetWeaponsType(this IEnumerable<Weapon> weapons, string type)
{
return new Data(this.Weapons.Where( a => a.type == type ).ToArray());
}
}
然后像这样使用:
Weapon[] weapons = new Weapon[]
{
// ...
};
weapons = new Data(weapons).unlocked().type("sword").andMore().andEvenMore().Weapons;
答案 2 :(得分:1)
public static class WeaponFilters
{
public static Weapon[] GetUnlocked(this Weapon[] w)
{
return w.Where(x=> x.unlocked).ToArray();
}
public static Weapon[] Type(this Weapon[] w, string type)
{
return w.Where(x=> x.type == type).ToArray();
}
//some more filters...
}
然后您可以像:
一样使用它weapons = weapons.unlocked().type("sword");