C#类型转换基类/接口与泛型方法

时间:2015-04-09 16:38:21

标签: c# generics inheritance

假设我有一个带共享接口的简单继承结构:

public interface IMammal
{
  ...
}

public class Human : IMammal
{
  ...
}

public class Animal : IMammal
{
  ...
}

并且在另一个类(Main.cs或其他)中说,我想实现一个方法。以下哪项是“最佳实践”:

public void MyFunction(IMammal input)
{
   // Do cool things with the IMammal.
}

或者

public void MyFunction<T>(T input) where T : IMammal
{
   // Do the same cool things with the IMammal.
}

注意:在这个简单的情况下,一个可能的解决方案是使IMammal成为一个抽象类,并在该抽象类中实现MyFunction。我需要保持IMammal接口。

5 个答案:

答案 0 :(得分:2)

最佳实践通常是第一种情况,并让底层运行时的多态行为为您处理类型。除非你特别需要知道类型(以及作为通用!),否则最好不要传递它。

第二个选项的情况是在你打算调用其他需要通用的方法时,例如那些操纵集合或序列化,以及必须处理T的方法对象的实际类型。然而,这是非常罕见且非常特殊的行为,所以最好只在绝对必要时使用它。

答案 1 :(得分:1)

这取决于MyFunction 做什么。如果MyFunction的工作原理与没有泛型的设计相同,那么请保持这种方式 - 使用多态通常比引入泛型更清晰。如果您使用泛型是有益的(例如添加到List<T>而不是List<Mammal>,那么请切换到泛型。

创建工作的代码,然后专注于使其更好

答案 2 :(得分:0)

我认为第一个更好,我的意思是,如果你正在调用其他类,你应该通过接口而不是类。

public void MyFunction(Mammal input)
{
   // Do cool things with the mammal.
}

此外,最好将接口称为IMammal而不是哺乳动物。

那是因为MyFunction是另一个类的方法,根据最佳实践,最好是注入一个接口而不是一个对象。

答案 3 :(得分:0)

在您的特定情况下,我通常会选择第一个选项。

但是,对于更复杂的场景,第二个选项更好,因为它允许您进一步指定类型约束,例如从多个接口继承,或者类和接口等。 例如,如果您还在方法的new()子句中包含where,它还允许您实例化新的T对象。

答案 4 :(得分:0)

我看到两个实现是等价的。那么简单就是最好的,所以选择#1我更喜欢。

如果MyFunction是Mammal的行为,它应该在界面中。如果你做了一些验证,例如并且需要更高层的其他东西,那么把它放在其他类中应该很好。