C# 根据基类类型添加到容器中的正确列表

C# 根据基类类型添加到容器中的正确列表,c#,.net,C#,.net,我有一个容器类,它包含许多对象列表,这些对象都继承自一个公共基类。如果我只有基类型,如何添加到此类?性能至关重要,因此我希望避免不必要的铸造 class Base { } class A : Base { } class B : Base { } class C : Base { } class Container { List<A> listA = new List<A>(); List<B> listB = new Lis

我有一个容器类,它包含许多对象列表,这些对象都继承自一个公共基类。如果我只有基类型,如何添加到此类?性能至关重要,因此我希望避免不必要的铸造

class Base {

}

class A : Base {

}

class B : Base {

}

class C : Base {

}


class Container
{
    List<A> listA = new List<A>();
    List<B> listB = new List<B>();
    List<C> listC = new List<C>();

    public Add(A a) => listA.Add(a);
    public Add(B b) => listB.Add(b);
    public Add(C c) => listC.Add(c);
}


Container container = new Container;
Base base = someFactory.DoSomething(); // Returns an instance of a, b, or c.
container.Add(base);
您有3种选择:

1-将listA、listB、listC合并到单个集合中:列表和合并将方法添加到AddBase b

2-将添加方法合并到单个方法:

public Add(Base base) {
  if(base is A a) listA.Add(a);
  else if(base is B b) listB.Add(b);
  else if(base is C c) listB.Add(c);
  else throw new NotImplementedException()
}
3-将剂量测定方法更改为通用方法:

Container container = new Container;
container.Add(someFactory.DoSomething<A>());

我不知道您的情况,但在我看来,最后一个选项会更快。

性能至关重要-不是对每个人都适用吗?你试过什么?您可以添加一个重载AddBase,并使用as运算符和null检查将其添加到相应的列表中。您不使用它的原因是什么?您的容器列表中不应该有一个列表和一个Addbase吗。如果以后需要检查该容器中项目的类型,可以使用ifitem is进行检查。这是多态性未按应有方式使用的情况之一。您正在将参数类型降级为共享基类型,因此无法跟踪正在使用的派生类型。但实际上,您需要记住特定的派生类型,以便可以根据该类型做出决策。当DoSomething返回A、B或C的实例时,这意味着您需要处理这个返回的对象,而不知道它是A、B还是C。然而,您需要确切地知道它是哪种类型。您的期望与您的实际操作相冲突。@VidmantasBlazevicius:ifitem之类的解决方案是以最少的代码更改解决当前问题的最快方法。然而,这些问题往往源于错误地使用多态性来过度简化特定算法。一个更好的解决方案是改进所使用类型的设计,这样一来,所使用的派生类型所需的信息就不会丢失。这与速度无关,但这是正确的设计。工厂必须返回特定类型的具体对象,而不是基类型。所以我们需要一个单独的工厂函数DoSomething来返回每种类型。它可以是您建议的DoSomething的通用函数,也可以是具有不同名称DoSomethingA的函数。