为什么不是基于参数类型调用的最具体的方法

时间:2011-05-13 13:46:43

标签: c# oop polymorphism overloading

此处总OO noob问题。我在类

中有这两种方法
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继承Session)

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; }


}

5 个答案:

答案 0 :(得分:7)

嗯,你的假设是合理的,并且有些语言像你想象的那样有效。

你的代码看起来像这样:

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参数调用方法。 在第二个示例中,编译器同样生成对另一个方法的硬编码调用。

在其他语言中,方法调用是“动态的”,这意味着在运行时期间会考虑实际类型。对其参数进行多态化的方法称为“多方法”(它们不仅在它们定义的类中具有多态性,而且在参数上也是多态的,因此“多”) (编辑:修正错别字)

答案 1 :(得分:2)

我认为问题出在代码中的其他地方。如果您尝试此示例,则事情按预期工作:

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();
    }
}

你能发一个完整的例子吗?也许课程定义有问题......

答案 2 :(得分:1)

我为不知道为什么发生这种情况的细节而道歉,但我对如何解决它有了一个想法。

尝试放弃(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
   }
}

答案 3 :(得分:1)

正如Angel O'Sphere所说,C#没有多次发送,但您可以使用访客模式实现双重发送。

http://en.wikipedia.org/wiki/Visitor_pattern

答案 4 :(得分:0)

分配后dbSession的类型是什么?我认为这是你所期望的,但它可能是Session

另外,你真的需要用子类和父类重载这个方法吗?这似乎是一个奇怪的情况,你需要两者,并可能导致混淆。