为什么不根据参数类型调用最具体的方法
这里是 OO 菜鸟问题。我在一个类中有这两个方法
private void StoreSessionSpecific(LateSession dbSession, SessionViewModel session)
{
session.LateSessionViewModel.Guidelines = dbSession.Guidelines.ToList();
}
private void StoreSessionSpecific(Session dbSession, SessionViewModel session )
{
// nothing to do yet...
}
,当我使用 LateSession 类型的 dbSession (LateSession 继承 Session)调用 StoreSessionSpecific 时,
var dbSession = new LateSession();
StoreSessionSpecific(dbSession, session);
我希望调用最上面的一个方法。由于 dbSession 是 LateSession 类型。
@Paolo Tedesco 这就是类的定义方式。
public class Session
{
public int ID { get; set; }
public int SessionTypeId { get; set; }
public virtual SessionType SessionType { get; set; }
[Required]
public DateTime StartTime { get; set; }
[Required]
public DateTime EndTime { get; set; }
// Session duration in minutes
// public int SessionDuration { get; set; }
public virtual ICollection<Attendee> Attendees { get; set; }
}
public class LateSession : Session
{
public int MaxCriticalIncidentsPerUser { get; set; }
public int MaxResultCriticalIncidents { get; set; }
public virtual ICollection<Guideline> Guidelines { get; set; }
}
Total OO noob question here. I have these two methods in a class
private void StoreSessionSpecific(LateSession dbSession, SessionViewModel session)
{
session.LateSessionViewModel.Guidelines = dbSession.Guidelines.ToList();
}
private void StoreSessionSpecific(Session dbSession, SessionViewModel session )
{
// nothing to do yet...
}
And when I call StoreSessionSpecific with dbSession being of type LateSession (LateSession inherits Session)
var dbSession = new LateSession();
StoreSessionSpecific(dbSession, session);
I expected the top one to be called. Since dbSession is of type LateSession.
@Paolo Tedesco This is how the classes are defined.
public class Session
{
public int ID { get; set; }
public int SessionTypeId { get; set; }
public virtual SessionType SessionType { get; set; }
[Required]
public DateTime StartTime { get; set; }
[Required]
public DateTime EndTime { get; set; }
// Session duration in minutes
// public int SessionDuration { get; set; }
public virtual ICollection<Attendee> Attendees { get; set; }
}
public class LateSession : Session
{
public int MaxCriticalIncidentsPerUser { get; set; }
public int MaxResultCriticalIncidents { get; set; }
public virtual ICollection<Guideline> Guidelines { get; set; }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
嗯,你的假设是合理的,并且有些语言的效果就像你想象的那样。
那么您的代码看起来像这样:
还是看起来像这样:
在第一个示例中,编译器假装不知道“s”的实际类型是什么,并使用 Session 参数对方法的调用进行硬编码。
同样,在第二个示例中,编译器生成对另一个方法的硬编码调用。
在其他语言中,方法调用是“动态的”,这意味着在运行时会考虑实际类型。参数多态的方法称为“多方法”(它们不仅在定义的类上多态,而且在参数上也多态,因此是“多”)
(编辑:修正错别字)
Well, your assumption is plausible and there are languages where it had worked like you thought.
So does your code look like this:
or does it look like this:
In the first example the compiler prettends not to know what the actual type of "s" is and hard codes the invocation of the method with the Session argument.
In the second example likewise the compiler generates a hard coded call to the other method.
In other languages the method call is "dynamic", that means during runtime the actuall types are considered. Methods that are polymorphic on their arguments are called "multimethods" (They are not only polymorphic on the class they are defined in but also on the arguments, hence "multi")
(Edit: fixed typos)
我认为问题出在您代码的其他地方。如果您尝试这个示例,一切都会按预期进行:
您可以发布一个完整的示例吗?也许类定义有问题......
I think the problem is somewhere else in your code. If you try this example, things work as expected:
Could you post a complete example? maybe there's a problem with the class definitions...
我很抱歉不知道为什么会发生这种情况,但我有一个解决方法的想法。
尝试释放
(LateSession, SessionViewModel)
重载,并在(Session, SessionViewModel)
重载中考虑 LateSession,如下所示:I apologize for not knowing the specifics of why this happens, but I have an idea on how to work around it.
Try loosing the
(LateSession, SessionViewModel)
overload, and account for LateSession in the(Session, SessionViewModel)
overload like:正如 Angel O'Sphere 所说,C# 没有多重分派,但是您可以使用访问者模式实现双重分派。
http://en.wikipedia.org/wiki/Visitor_pattern
As Angel O'Sphere said, C# doesn't have multiple dispatch however you can implement double dispatch using Visitor Pattern.
http://en.wikipedia.org/wiki/Visitor_pattern
分配后的 dbSession 的类型是什么?我假设这就是您所期望的,但它可能是一个
Session
。另外,您真的需要用子类和父类重载此方法吗?这似乎是一个奇怪的情况,您需要两者,并且可能会导致混乱。
What is the type of
dbSession
after that assignment? I would assume it is what you expect, but it could be aSession
.Separately, do you really need to overload this method with both a child and parent class? It seems like a strange case where you would need both, and will likely lead to confusion.