我需要拆分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>
}
答案 0 :(得分:11)
您可以按类型执行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)];
正如蒂姆在评论中所说:
var grouped = lst.ToLookup(i => i.GetType());
答案 1 :(得分:4)
您可以使用OfType扩展程序:
var dogs = lst.OfType<Dog>().ToList();
var cats = lst.OfType<Cat>().ToList();
var parrots = lst.OfType<Carrot>().ToList();
答案 2 :(得分:3)
虽然这里已有答案。他们的实现都使用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}");
答案 3 :(得分:1)
你可以使用linq来过滤你正在寻找的类型的那些,但是如果你试图将所有实现的任何列表中的内容分解,那可能会很棘手并且你必须使用反射< / p>
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()
答案 4 :(得分:0)
你可以更好地使用
import {AdminHomeComponent} from "./components/admin-home.component";
import {AdminHomeComponent} from "./Components/admin-home.component";