C# 按实现拆分接口列表
C# split List of interface by implementations
我需要拆分 List<IInterface>
以获得 IInterface
的具体实现列表。
我怎样才能以最佳方式做到这一点?
public interface IPet { }
public class Dog :IPet { }
public class Cat : IPet { }
public class Parrot : IPet { }
public void Act()
{
var lst = new List<IPet>() {new Dog(),new Cat(),new Parrot()};
// I need to get three lists that hold each implementation
// of IPet: List<Dog>, List<Cat>, List<Parrot>
}
你可以使用 linq 来过滤你正在寻找的类型,但是如果你试图将事情分解成所有实现的任何列表,这可能很棘手,你必须使用倒影
var dogs = lst.Where(x => x is Dog).ToList()
var cats = lst.Where(x => x is Cat).ToList()
var parrots = lst.Where(x => x is Parrot).ToList()
您可以按类型执行 GroupBy
:
var grouped = lst.GroupBy(i => i.GetType()).Select(g => g.ToList()).ToList()
如果您想要按类型分类的字典,您可以这样做:
var grouped = lst.GroupBy(i => i.GetType()).ToDictionary(g => g.Key, g => g.ToList());
var dogList = grouped[typeof(Dog)];
或者正如 Tim 在评论中建议的那样:
var grouped = lst.ToLookup(i => i.GetType());
您可以使用 OfType 扩展名:
var dogs = lst.OfType<Dog>().ToList();
var cats = lst.OfType<Cat>().ToList();
var parrots = lst.OfType<Carrot>().ToList();
虽然这里已经有了答案。他们的实现都使用 linq 并创建许多新列表和数据传递,这里是一个更高效但不那么漂亮的单传递实现。
这里有一些代码将我的方法与此处的所有其他方法进行比较:
首先输出:
使用 heinzbeinz 花费的时间:6533
使用 Arturo Menchaca 花费的时间:6450
使用 johnny 5 花费的时间:5261
使用 Matt Clark(无 linq)花费的时间:2072
Stopwatch sw = new Stopwatch();
sw.Start();
for (int k = 0; k < 1000000; k++)
{
// heinzbeinz
var petLists = pets.GroupBy(i => i.GetType()).Select(g => g.ToList()).ToList();
}
sw.Stop();
Console.WriteLine($"Time taken using heinzbeinz: {sw.ElapsedMilliseconds}");
sw.Reset();
sw.Start();
for (int k = 0; k < 1000000; k++)
{
// Arturo Menchaca
var dogs = pets.OfType<Dog>().ToList();
var cats = pets.OfType<Cat>().ToList();
var parrots = pets.OfType<Parrot>().ToList();
}
sw.Stop();
Console.WriteLine($"Time taken using Arturo Menchaca: {sw.ElapsedMilliseconds}");
sw.Reset();
sw.Start();
for (int k = 0; k < 1000000; k++)
{
// johnny 5
var dogs = pets.Where(x => x is Dog).ToList();
var cats = pets.Where(x => x is Cat).ToList();
var parrots = pets.Where(x => x is Parrot).ToList();
}
sw.Stop();
Console.WriteLine($"Time taken using johnny 5: {sw.ElapsedMilliseconds}");
sw.Reset();
sw.Start();
for (int k = 0; k < 1000000; k++)
{
// Matt Clark
var dogs = new List<Dog>();
var cats = new List<Cat>();
var parrot = new List<Parrot>();
foreach (var pet in pets)
{
if (pet is Dog)
{
dogs.Add(pet as Dog);
}
if (pet is Cat)
{
cats.Add(pet as Cat);
}
if (pet is Parrot)
{
parrot.Add(pet as Parrot);
}
}
}
sw.Stop();
Console.WriteLine($"Time taken using Matt Clark (no linq): {sw.ElapsedMilliseconds}");
你最好使用
var dogs = lst.OfType<Dog>().ToList()
var cats = lst.OfType<Cat>().ToList()
var parrots = lst.OfType<Parrot>().ToList()
我需要拆分 List<IInterface>
以获得 IInterface
的具体实现列表。
我怎样才能以最佳方式做到这一点?
public interface IPet { }
public class Dog :IPet { }
public class Cat : IPet { }
public class Parrot : IPet { }
public void Act()
{
var lst = new List<IPet>() {new Dog(),new Cat(),new Parrot()};
// I need to get three lists that hold each implementation
// of IPet: List<Dog>, List<Cat>, List<Parrot>
}
你可以使用 linq 来过滤你正在寻找的类型,但是如果你试图将事情分解成所有实现的任何列表,这可能很棘手,你必须使用倒影
var dogs = lst.Where(x => x is Dog).ToList()
var cats = lst.Where(x => x is Cat).ToList()
var parrots = lst.Where(x => x is Parrot).ToList()
您可以按类型执行 GroupBy
:
var grouped = lst.GroupBy(i => i.GetType()).Select(g => g.ToList()).ToList()
如果您想要按类型分类的字典,您可以这样做:
var grouped = lst.GroupBy(i => i.GetType()).ToDictionary(g => g.Key, g => g.ToList());
var dogList = grouped[typeof(Dog)];
或者正如 Tim 在评论中建议的那样:
var grouped = lst.ToLookup(i => i.GetType());
您可以使用 OfType 扩展名:
var dogs = lst.OfType<Dog>().ToList();
var cats = lst.OfType<Cat>().ToList();
var parrots = lst.OfType<Carrot>().ToList();
虽然这里已经有了答案。他们的实现都使用 linq 并创建许多新列表和数据传递,这里是一个更高效但不那么漂亮的单传递实现。 这里有一些代码将我的方法与此处的所有其他方法进行比较:
首先输出:
使用 heinzbeinz 花费的时间:6533
使用 Arturo Menchaca 花费的时间:6450
使用 johnny 5 花费的时间:5261
使用 Matt Clark(无 linq)花费的时间:2072
Stopwatch sw = new Stopwatch();
sw.Start();
for (int k = 0; k < 1000000; k++)
{
// heinzbeinz
var petLists = pets.GroupBy(i => i.GetType()).Select(g => g.ToList()).ToList();
}
sw.Stop();
Console.WriteLine($"Time taken using heinzbeinz: {sw.ElapsedMilliseconds}");
sw.Reset();
sw.Start();
for (int k = 0; k < 1000000; k++)
{
// Arturo Menchaca
var dogs = pets.OfType<Dog>().ToList();
var cats = pets.OfType<Cat>().ToList();
var parrots = pets.OfType<Parrot>().ToList();
}
sw.Stop();
Console.WriteLine($"Time taken using Arturo Menchaca: {sw.ElapsedMilliseconds}");
sw.Reset();
sw.Start();
for (int k = 0; k < 1000000; k++)
{
// johnny 5
var dogs = pets.Where(x => x is Dog).ToList();
var cats = pets.Where(x => x is Cat).ToList();
var parrots = pets.Where(x => x is Parrot).ToList();
}
sw.Stop();
Console.WriteLine($"Time taken using johnny 5: {sw.ElapsedMilliseconds}");
sw.Reset();
sw.Start();
for (int k = 0; k < 1000000; k++)
{
// Matt Clark
var dogs = new List<Dog>();
var cats = new List<Cat>();
var parrot = new List<Parrot>();
foreach (var pet in pets)
{
if (pet is Dog)
{
dogs.Add(pet as Dog);
}
if (pet is Cat)
{
cats.Add(pet as Cat);
}
if (pet is Parrot)
{
parrot.Add(pet as Parrot);
}
}
}
sw.Stop();
Console.WriteLine($"Time taken using Matt Clark (no linq): {sw.ElapsedMilliseconds}");
你最好使用
var dogs = lst.OfType<Dog>().ToList()
var cats = lst.OfType<Cat>().ToList()
var parrots = lst.OfType<Parrot>().ToList()