为什么不根据参数类型调用最具体的方法
本文关键字:方法 调用 参数 类型 为什么不 | 更新日期: 2023-09-27 17:56:26
这里的 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...
}
当我调用 StoreSessionSpecific 时,dbSession 的类型为 LateSession(LateSession 继承会话)
var dbSession = new LateSession();
StoreSessionSpecific(dbSession, session);
我以为会叫最上面的那个。由于数据库会话的类型是 LateSession。
@Paolo特德斯科 这就是类的定义方式。
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; }
}
嗯,你的假设是合理的,有些语言就像你想象的那样工作。
所以你的代码看起来像这样:
Session s = new LateSession(); // the compiler only "knows" that s is of type Session
StoreSessionSpecific(s);
或者它看起来像这样:
LateSession ls = new LateSession(); // the compiler knows that ls is in fact a LateSession
StoreSessionSpecific(ls);
在第一个示例中,编译器假装不知道"s"的实际类型是什么,并使用 Session 参数对方法的调用进行硬编码。同样,在第二个示例中,编译器生成对另一个方法的硬编码调用。
在其他语言中,方法调用是"动态的",这意味着在运行时会考虑精算类型。在其参数上是多态的方法称为"多方法"(它们不仅在定义它们的类上是多态的,而且在参数上也是多态的,因此是"多的")(编辑:修正错别字)
我认为问题出在您的代码中的其他地方。如果您尝试此示例,事情将按预期工作:
class Base {
}
class Derived : Base {
}
class Something {
private void DoSomething(Base b) {
Console.WriteLine("DoSomething - Base");
}
private void DoSomething(Derived d) {
Console.WriteLine("DoSomething - Derived");
}
public void Test() {
var d = new Derived();
DoSomething(d);
}
}
static class Program {
static void Main(params string[] args) {
Something something = new Something();
something.Test();
}
}
你能发布一个完整的例子吗? 也许类定义有问题...
我很抱歉不知道为什么会发生这种情况的细节,但我有一个关于如何解决它的想法。
尝试丢失(LateSession, SessionViewModel)
重载,并在(Session, SessionViewModel)
重载中考虑 LateSession,如下所示:
private void StoreSessionSpecific(Session dbSession, SessionViewModel session )
{
if (dbSession is LateSession) {
// handle as LateSession
} else {
// handle as base-class Session
}
}
正如 Angel O'Sphere 所说,C# 没有多重调度,但是您可以使用访客模式实现双重调度。
http://en.wikipedia.org/wiki/Visitor_pattern
作业后的dbSession
类型是什么? 我认为这是您所期望的,但这可能是一个Session
.
另外,你真的需要使用子类和父类重载此方法吗? 这似乎是一个奇怪的情况,您需要两者,并且可能会导致混乱。