在c#中实现多态性,如何做到最好?

[英]implementing polymorphism in c#, how best to do it?


first question here, so hopefully you'll all go gently on me!

第一个问题在这里,所以希望你们都会轻轻地对我说话!

I've been reading an awful lot over the past few days about polymorphism, and trying to apply it to what I do in c#, and it seems there are a few different ways to implement it. I hope I've gotten a handle on this, but I'd be delighted even if I haven't for clarification.

过去几天我一直在阅读关于多态性的很多内容,并试图将它应用到我在c#中所做的事情,似乎有几种不同的方法来实现它。我希望我已经掌握了这个,但即使我没有澄清,我也很高兴。

From what I can see, I've got 3 options:

从我所看到的,我有3个选择:

  1. I can just inherit from a base class and use the keyword 'virtual' on any methods that I want my derived classes to override.
  2. 我可以从基类继承并在我希望派生类重写的任何方法上使用关键字'virtual'。

  3. I could implement an abstract class with virtual methods and do it that way,
  4. 我可以用虚方法实现一个抽象类,并以这种方式实现,

  5. I could use an interface?
  6. 我可以使用界面吗?

From what I can see, if I don't require any implementation logic in the base, then an interface gives me the most flexibility (as I'm then not limiting myself with regards multiple inheritance etc.), but if I require the base to be able to do something on top of whatever the derived classes are doing, then going with either 1 or 2 would be the better solution?

从我所看到的,如果我不需要基础中的任何实现逻辑,那么一个接口给了我最大的灵活性(因为我当然不限制我自己的多重继承等),但如果我需要基础为了能够在派生类正在做的事情之上做一些事情,那么使用1或2将是更好的解决方案?

Thanks for any input on this guys - I have read so much this weekend, both on this site and elsewhere, and I think I understand the approaches now, yet I just want to clarify in a language specific way if I'm on the right track. Hopefully also I've tagged this correctly.

感谢有关这些人的任何意见 - 本周末我已阅读了很多内容,无论是在本网站还是其他地方,我认为我现在理解这些方法,但我只是想以语言特定的方式澄清如果我在右边跟踪。希望我也正确地标记了这一点。

Cheers, Terry

6 个解决方案

#1


An interface offers the most abstraction; you aren't tied to any specific implementation (useful if the implementation must, for other reasons, have a different base class).

界面提供最多的抽象;您不依赖于任何特定的实现(如果由于其他原因,实现必须具有不同的基类,则非常有用)。

For true polymorphism, virtual is a must; polymorphism is most commonly associated with type subclassing...

对于真正的多态性,虚拟是必须的;多态性最常与类型子类化相关联......

You can of course mix the two:

你当然可以混合两者:

public interface IFoo {
    void Bar();
}
class Foo : IFoo {
    public virtual void Bar() {...}
}
class Foo2 : Foo {
    public override ...
} 

abstract is a separate matter; the choice of abstract is really: can it be sensibly defined by the base-class? If there is there no default implementation, it must be abstract.

摘要是一个单独的问题;抽象的选择确实是:它可以由基类理智地定义吗?如果没有默认实现,则它必须是抽象的。

A common base-class can be useful when there is a lot of implementation details that are common, and it would be pointless to duplicate purely by interface; but interestingly - if the implementation will never vary per implementation, extension methods provide a useful way of exposing this on an interface (so that each implementation doesn't have to do it):

当存在许多常见的实现细节时,常见的基类可能很有用,并且纯粹通过接口复制是没有意义的;但有趣的是 - 如果实现永远不会因每个实现而有所不同,那么扩展方法提供了一种在接口上公开它的有用方法(这样每个实现都不必这样做):

public interface IFoo {
    void Bar();
}
public static class FooExtensions {
    // just a silly example...
    public static bool TryBar(this IFoo foo) {
        try {
             foo.Bar();
             return true;
        } catch {
             return false;
        }
    }
}

#2


All three of the above are valid, and useful in their own right. There is no technique which is "best". Only programming practice and experience will help you to choose the right technique at the right time.

以上所有三个都是有效的,并且本身就是有用的。没有“最好”的技术。只有编程实践和经验才能帮助您在合适的时间选择合适的技术。

So, pick a method that seems appropriate now, and implement away. Watch what works, what fails, learn your lessons, and try again.

因此,选择一个现在似乎合适的方法,并实施。观察哪些有效,哪些失败,吸取教训,然后再试一次。

#3


Interfaces are usually favored, for several reasons :

接口通常受到青睐,原因如下:

  • Polymorphisme is about contracts, inheritance is about reuse
  • Polymorphisme是关于契约,继承是关于重用

  • Inheritance chains are difficult to get right (especially with single inheritance, see for instance the design bugs in the Windows Forms controls where features like scrollability, rich text, etc. are hardcoded in the inheritance chain
  • 继承链很难正确(特别是单继承,请参阅Windows窗体控件中的设计错误,其中可滚动性,富文本等功能在继承链中进行了硬编码

  • Inheritance causes maintenance problems
  • 继承会导致维护问题

That said, if you want to leverage common functionnality, you can use interfaces for polymorphism (have your methods accept interfaces) but use abstract base classes to share some behavior.

也就是说,如果你想利用常见的功能,你可以使用接口进行多态(让你的方法接受接口),但使用抽象基类来共享一些行为。

public interface IFoo
{
    void Bar();
    enter code here
}

will be your interface

将是你的界面

public abstract class BaseFoo : IFoo
{
    void Bar
  {
        // Default implementation
  }
}

will be your default implementation

将是您的默认实现

public class SomeFoo : BaseFoo
{

}

is a class where you reuse your implementation.

是一个重用您的实现的类。

Still, you'll be using interfaces to have polymorphism:

不过,您将使用接口来实现多态:

public class Bar
{
   int DoSometingWithFoo(IFoo foo)
{

    foo.Bar();
}
}

notice that we're using the interface in the method.

注意我们正在使用方法中的接口。

#4


The first thing you should ask is "why do I need to use polymorphism?", because polymorphism is not and end by itself, but a mean to reach an end. Once you have your problem well defined, it should be more clear which approach to use.

你应该问的第一件事是“为什么我需要使用多态?”,因为多态性本身并不是结束,而是达到目的的意思。一旦您明确定义了问题,就应该更清楚地使用哪种方法。

Anyway, those three aproaches you commented are not exclusive, you still can mix them if you need to reuse logic between just some classes but not others, or need some distinct interfaces...

无论如何,你评论的这三个方法并不是独占的,如果你需要在一些类之间重用逻辑而不是其他类,或者需要一些不同的接口,你仍然可以混合它们......

#5


  • use abstract classes to enforce a class structure
  • 使用抽象类来强制执行类结构

  • use interfaces for describing behaviors
  • 使用接口来描述行为

#6


It really depends on how you want to structure your code and what you want to do with it.

这实际上取决于您希望如何构建代码以及您希望如何使用它。

Having a base class of type Interface is good from the point of view of testing as you can use mock objects to replace it.

从测试的角度来看,具有Interface类型的基类是很好的,因为您可以使用模拟对象来替换它。

Abstract classes are really if you wish to implement code in some functions and not others, as if an abstract class has nothing other than abstract functions it is effectively an Interface.

如果您希望在某些函数中实现代码而不是其他函数,那么抽象类就是如此,就像抽象类只有抽象函数一样,它实际上是一个接口。

Remember that an abstract class cannot be instantiated and so for working code you must have a class derived from it.

请记住,抽象类无法实例化,因此对于工作代码,您必须具有从中派生的类。

In practice all are valid.

实际上所有都是有效的。

I tend to use an abstract class if I have a lot of classes which derive from it but on a shallow level (say only 1 class down).

我倾向于使用抽象类,如果我有很多类派生自它,但是在浅层(比如说只有1个类)。

If I am expecting a deep level of inheritence then I use a class with virtual functions.

如果我期待深层次的继承,那么我使用具有虚函数的类。

Eitherway it's best to keep classes simple, along with their inheritence as the more complex they become the more likelyhood of introducing bugs.

无论如何,最好保持简单的类,以及它们的继承性,因为它们越复杂,它们就越有可能引入错误。

智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2009/06/01/7202752d56ecb9eb6c421a900ea59459.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告