【发布时间】:2020-01-09 12:10:16
【问题描述】:
背景
我的代码接收一些 IProduct 类型的反序列化数据,但在运行时实现类是未知的。我应该将此数据传递给一个接受实现类实例的重载方法。
这可以通过使用 switch 语句来实现,但它看起来很笨重并且需要大量代码。我已经通过对单个实体使用后期绑定和运行时编译解决了这个问题,但我无法弄清楚如何为集合执行此操作。
解决单个实体的问题
如果我有一个 IProduct 类型的对象,并且想将它传递给正确的重载方法,该方法接受一个实现类,如玩具、食品、汽车或其他东西。如何在不创建大 switch 语句的情况下实现这一点?
给定以下方法和接口:
public interface IProduct
{
string Name { get;}
double Price { get;}
}
public void Store(Apple apple);
public void Store(Toy toy);
public void Store(Car car);
使用 switch 语句,它看起来像这样:
IProduct product = new Apple();
switch (product)
{
case Apple apple:
Store(apple);
break;
case Toy toy:
Store(toy);
break;
case Car car:
Store(car);
break;
}
我已经设法使用后期绑定和运行时编译将其减少到以下。
IProduct product = new Apple();
Store((dynamic)product);
问题
但是,当涉及到集合时,我无法弄清楚如何以类似的方式进行后期绑定。
给定以下方法:
public static void Store(ICollection<Apple> apples);
public static void Store(ICollection<Toy> toys);
public static void Store(ICollection<Car> cars);
我如何通过这个:
ICollection<IProduct> products = new List<IProduct>() { new Apple()};
有没有办法在不使用大量神奇代码的情况下实现相同的目标?
【问题讨论】:
-
你不会,好吧,不是没有一些黑客攻击。从根本上说,您违反了 SOLID 原则。如果你有一个苹果列表,那么使用一个苹果列表。如果您有一个产品列表,则将每个项目视为一个产品。
-
这当然是一个简单的例子。我有兴趣解决这个问题或解释为什么不可能。只是出于兴趣,当我只提供 DTO 和一个接口时,您如何断定这违反了 SOLID,违反了哪些 SOLID 原则?
标签: c# dynamic polymorphism late-binding