我正在尝试创建泛型方法来过滤几个方法的结果,这些方法返回从相同基类型派生的类型列表。我准备了我的问题的简化版本:
using System;
using System.Collections.Generic;
using System.Linq;
public class Animal
{
public string Name { get; set; }
}
public class Cat : Animal { }
public class Dog : Animal { }
public class Program
{
public static void Main()
{
Console.WriteLine(GetFilteredAnimals("Pe", GetCats));
}
private static List<Cat> GetCats()
{
return new List<Cat>() { new Cat { Name = "Sphinx" }, new Cat { Name = "Persian" } };
}
private static List<Dog> GetDogs()
{
return new List<Dog>() { new Dog { Name = "Bulldog"}, new Dog { Name = "Dalmatian" } };
}
private static List<Animal> GetFilteredAnimals(string f, Func<List<Animal>> method)
{
var animals = method();
return animals.Where(a => a.Name.StartsWith(f)).ToList<Animal>();
}
}
方法
GetFilteredAnimals("Pe", GetCats)
无效,因为GetCats
未返回Animal
列表。是否可以为列表执行此类通用方法?据我所知,如果我使用单个对象而不是列表,它将起作用。
此工作代码为here on .NET Fiddle
答案 0 :(得分:2)
假设您正在使用C#4+和.NET 4+,您可以使用generic covariance来实现此功能:
private static List<Animal> GetFilteredAnimals(string f, Func<IEnumerable<Animal>> method)
List<Cat>
不能被视为List<Animal>
- 但可以被视为IEnumerable<Animal>
,因为IEnumerable<T>
是协变的T
。
同样Func<T>
在T
中是协变的,因此Func<List<Cat>>
可以被视为Func<IEnumerable<Animal>>
...因此它会编译。