C#split按实现划分的接口列表

时间:2016-09-20 20:24:14

标签: c# list interface split implementation

我需要拆分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>
        }

5 个答案:

答案 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";