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



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

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的界面。

最佳做法通常是第一种情况,让基础运行时的多态行为为您处理类型。除非你特别需要知道类型(并且作为泛型!),否则最好不要传递它。

当您

要调用需要泛型的其他方法(例如那些操作集合或序列化的方法)并且必须处理T而不是对象的实际类型时,会出现第二个选项的情况。然而,这是非常罕见和非常具体的行为,因此最好仅在绝对必要时使用它。

这取决于MyFunction做什么。 如果MyFunction按照设计工作,没有泛型,那么就保持这种方式 - 使用多态性通常比引入泛型更干净。 如果您到了使用泛型是有益的地步(例如,例如添加到List<T>而不是List<Mammal>那么切换到泛型。

创建有效的代码,然后专注于使其更好

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

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

此外,最好是校准界面IMammal而不是哺乳动物。

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

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

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

我看到两个实现是等效的。然后简单是最好的,所以我更喜欢选项 #1。

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

最新更新