当方法返回类型包含接口时,使方法泛型的任何缺点

本文关键字:方法 泛型 缺点 任何 返回类型 包含 接口 | 更新日期: 2023-09-27 18:15:27

考虑如下方法:

IEnumerable<IFoo> DoSomethingRequiringIFooInterface(IEnumerable<IFoo> foos)

,其中方法使用IFoo接口(可能用于过滤或排序),但它没有创建实现IFoo的新对象。

总是不是更好的方法是通用的,如:

IEnumerable<TFoo> DoSomethingRequiringIFooInterface<TFoo>(IEnumerable<TFoo> foos)
    where TFoo : IFoo

以便客户端可以保留类型?或者是否存在一些缺点(或某些情况下),您不希望这样做?

谢谢!

当方法返回类型包含接口时,使方法泛型的任何缺点

一个可能的缺点是如果你想重载这个方法:

void F(IFoo x) {}
void F(IBar x) {}

工作好。但

void F<T>(T x) where T : IFoo {}
void F<T>(T x) where T : IBar {}

不能编译,因为这两个方法现在具有相同的签名。

如果返回值可能是实现IFoo的不同类型的对象,而不是传入的对象,则不希望这样做。如果返回的所有元素需要至少具有与传入元素相同级别的类型特异性,则使用泛型版本是合适的。所以,如果你的函数总是返回SpecialFoo,如果提供了SpecialFoo,泛型方法是更合适的,因为它更严格地约束。

如果您使用反射来更改或分析代码,则可能存在一些缺点,因为使用反射处理的代码的复杂性更大,因此您必须编写更复杂的代码来完成此操作。

我更喜欢泛型方法,因为您总是可以使用IFoo指定方法,并且与使用非泛型方法具有相同的结果:

DoSomethingRequiringIFooInterface<IFoo>(...);

你也给用户更好的类型安全选项,因为他可以(if Foo1: IFoo):

DoSomethingRequiringIFooInterface<Foo1>(...);

确切地知道他得到了IEnumerable<Foo1>.

所以这意味着泛型方法更好,因为它给了用户更多的选项,除了需要写更多的文本之外,没有可用性缺点。

当您尝试将它用于两个不同的IFoo对象时,这有一个缺点。如:

DoSomethingRequiringIFooInterface({ new AFoo(), new BFoo() });

使用第一个版本,这将工作。而使用第二个则不行