简体   繁体   English

C#继承和方法签名

[英]C# inheritance and method signatures

I am working on a class that needs run a different process method based on the type of object I pass in. I thought that overloading might work here, but I have a question. 我正在研究一个需要根据我传入的对象类型运行不同的进程方法的类。我认为重载可能在这里工作,但我有一个问题。 Lets say I have two interfaces: 可以说我有两个接口:

public interface IEmail 
{
      Some properties ...
}

and

public interface ISpecialEmail : IEmail
{
     Some more properties....
}

and a class to process these objects: 以及处理这些对象的类:

 public class EmailProcessor
 {

      public void ProcessEmail (IEmail email)
      {
           do stuff;
      }

      public void ProcessEmail (ISpecialEmail email)
      {

          do different stuff
      }
 }

My question is, being that ISpecialEmail inherits from IEmail, are these method signatures sufficiently different to allow for overloading? 我的问题是,由于ISpecialEmail继承自IEmail,这些方法签名是否足够不同以允许重载? My original thought is that ISpecialEmail emails would also trigger the IEmail signature because technically that interface is implemented also. 我最初的想法是,ISpecialEmail电子邮件也会触发IEmail签名,因为从技术上讲,该接口也是实现的。

Thanks for your help. 谢谢你的帮助。

It depends on how you call the methods. 这取决于你如何调用方法。

For example, assume you have Email : IEmail and SpecialEmail : ISpecialEmail . 例如,假设您有Email : IEmailSpecialEmail : ISpecialEmail If you declared a list of emails: 如果您声明了电子邮件列表:

List<IEmail> emails = new List<IEmail> {new Email(), new SpecialEmail()};

And then ran 然后跑了

foreach (var email in emails) { EmailProcessor.ProcessEmail(email) }

It will call public void ProcessEmail (IEmail email) for both - because the call binding happens at compile time (ie it wouldn't work the way you wanted). 它会为两者调用public void ProcessEmail (IEmail email) - 因为调用绑定在编译时发生(即它不会按照你想要的方式工作)。

It would also fail if you did something like: 如果您执行以下操作,它也会失败:

var email = GetEmail(); // returns either IEmail or IExtendedEmail
EmailProcessor.ProcessEmail(email); // Would ONLY call ProcessEmail(IEmail)

So, polymorphism would fail with those signatures. 因此,多态性将与这些签名失败。

However, the following would work: 但是,以下方法可行:

var email = GetEmail(); // returns only IEmail
var extendedEmail = GetExtendedEmail(); // returns only IExtendedEmail
EmailProcessor.ProcessEmail(email); // Would all ProcessEmail(IEmail)
EmailProcessor.ProcessEmail(extendedEmail ); // Would call ProcessEmail(IExtendedEmail)

According to the C# spec (section 7.4.3) 根据C#规范(第7.4.3节)

"methods in a base class are not candidates if any method in a derived class is applicable" “如果派生类中的任何方法适用,则基类中的方法不是候选者”

public void ProcessEmail (ISpecialEmail email) should be the function called if an ISpecialEmail is passed in. Be careful about casting it down to an IEmail , though, as that will change the precedence. public void ProcessEmail (ISpecialEmail email)应该是传入ISpecialEmail调用的函数。但是要注意将其转换为IEmail ,因为这会改变优先级。 If you're combining all of the emails, both of types IEmail and ISpecialEmail into one List of IEmail s for processing, they'll all go through the IEmail version of the function. 如果你将所有的电子邮件, IEmailISpecialEmail这两种类型的邮件ISpecialEmail到一个IEmail List中进行处理,它们都将通过该函数的IEmail版本。

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

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