C#继承和方法签名
本文关键字:方法 继承 | 更新日期: 2023-09-27 18:19:26
我正在开发一个类,该类需要根据传入的对象类型运行不同的处理方法。我认为重载可能在这里起作用,但我有一个问题。假设我有两个接口:
public interface IEmail
{
Some properties ...
}
和
public interface ISpecialEmail : IEmail
{
Some more properties....
}
和一个处理这些对象的类:
public class EmailProcessor
{
public void ProcessEmail (IEmail email)
{
do stuff;
}
public void ProcessEmail (ISpecialEmail email)
{
do different stuff
}
}
我的问题是,由于ISpecialEmail继承自IEmail,这些方法签名的差异是否足以允许重载?我最初的想法是,ISpecialEmail电子邮件也会触发IEmail签名,因为从技术上讲,该接口也是实现的。
谢谢你的帮助。
这取决于如何调用方法。
例如,假设您有Email : IEmail
和SpecialEmail : ISpecialEmail
。如果您申报了电子邮件列表:
List<IEmail> emails = new List<IEmail> {new Email(), new SpecialEmail()};
然后运行
foreach (var email in emails) { EmailProcessor.ProcessEmail(email) }
它将为和调用public void ProcessEmail (IEmail email)
,因为调用绑定发生在编译时(即,它不会按您想要的方式工作)。
如果你做了这样的事情,它也会失败:
var email = GetEmail(); // returns either IEmail or IExtendedEmail
EmailProcessor.ProcessEmail(email); // Would ONLY call ProcessEmail(IEmail)
因此,多态性会因这些签名而失败。
然而,以下方法可行:
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)
根据C#规范(第7.4.3节)
"如果派生类中的任何方法都适用,则基类中的方法不是候选方法"
如果传入ISpecialEmail
,则public void ProcessEmail (ISpecialEmail email)
应该是调用的函数。不过,请小心将其强制转换为IEmail
,因为这会更改优先级。如果您将所有类型为IEmail
和ISpecialEmail
的电子邮件合并为IEmail
的一个List
进行处理,它们都将通过IEmail
版本的函数。