简体   繁体   English

C#类型转换基础类/接口与通用方法

[英]C# Type casting base class / interface vs. generic method

Say I have a simple inheritance structure with a shared interface: 说我有一个带有共享接口的简单继承结构:

public interface IMammal
{
  ...
}

public class Human : IMammal
{
  ...
}

public class Animal : IMammal
{
  ...
}

And say in a different class (Main.cs or whatever), I want to implement a method. 并在另一个类(Main.cs或其他类)中说,我想实现一个方法。 Which of the following is the "best practice": 以下哪项是“最佳实践”:

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

Or 要么

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

Note: A possible solution in this simple case would be to make IMammal an abstract class and implement MyFunction in that abstract class. 注意:在这种简单情况下,可能的解决方案是使IMammal成为抽象类,并在该抽象类中实现MyFunction。 I need to keep the IMammal an interface though. 我需要保持IMammal一个接口。

The best practice would usually to be the first case, and let the polymorphic behaviour of the underlying runtime handle types for you. 最佳实践通常是第一种情况,并让基础运行时的多态行为为您处理类型。 Unless you specifically need to know the type (and as a generic!) it's best not to pass that around. 除非您特别需要知道类型(并且作为泛型!),否则最好不要传递它。

the case for the second option comes in when you're going to be making calls to other methods which need to be generic, such as those manipulating collections or serialization, and which must deal with T instead of the actual type of the object. 当您要调用其他需要通用的方法(例如那些操纵集合或序列化并且必须处理T而不是对象的实际类型)的方法时,就会出现第二种选择。 This however is very rare and very specific behaviour, so it's better to use it only as absolutely necessary. 但是,这是非常罕见且非常具体的行为,因此最好仅在绝对必要的情况下使用它。

It depends on what MyFunction does . 这取决于MyFunction 功能 If MyFunction works just as designed without generics then leave it that way - using polymorphism is generally cleaner that introducing generics. 如果MyFunction在没有泛型的情况下按设计方式工作,则应采用这种方式-使用多态通常比引入泛型更干净。 If you get to a point where using generics is beneficial (eg like adding to a List<T> rather than a List<Mammal> then switch to generics. 如果到达使用泛型有益的地步(例如,像添加到List<T>而不是List<Mammal>切换到泛型。

Create code that works , then focus on making it better . 创建工作代码,然后专注于我们改进

I think it's better the first one, I mean than if you are calling other class you should pass the interface instead a class. 我认为最好是第一个,而不是如果您要调用其他类,则应该通过接口而不是类。

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

Also it's better to cal interface IMammal instead Mammal. 另外,最好校准IMammal而不是Mammal接口。

That's because MyFunction is a method of another class, according to best practices it's better to inject an Interface instead an object. 这是因为MyFunction是另一个类的方法,根据最佳实践,最好注入一个Interface而不是一个对象。

In your particular case, I would in general opt in for the first option. 对于您的特殊情况,我通常会选择第一种选择。

However, for more complex scenarios, 2nd option is better because it allows you to further specify the type constraints, such as inheriting from multiple interfaces, or a class and an interface etc. It will also for example allow you to instantiate new T objects, if you also include new() in the method's where clause. 但是,对于更复杂的情况,第二个选项更好,因为它允许您进一步指定类型约束,例如从多个接口,类和接口等继承。例如,它还可以实例化新的T对象,如果您还在方法的where子句中包含new()

I see two implementations are equivalent. 我看到两个实现是等效的。 Then simple be the best, so option #1 I prefer. 那么简单就是最好的选择,所以我更喜欢选择#1。

If MyFunction is a behavior of Mammal, it should be in the interface. 如果MyFunction是哺乳动物的行为,则应在界面中。 If you do some validation eg and requires something else from a higher layer for ex, put it in other class should be nice. 如果您进行了一些验证,例如,并且需要更高层次的ex进行其他验证,则将其放在其他类中应该很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM