Почему не самый специфический метод вызывается в зависимости от типа параметра - PullRequest
9 голосов
/ 13 мая 2011

Всего вопросов о нубе здесь.У меня есть эти два метода в классе

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 ]

7 голосов
/ 13 мая 2011

Что ж, ваше предположение правдоподобно, и есть языки, на которых это сработало, как вы думали.

Так выглядит ли ваш код так:

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. Во втором примере аналогичным образом компилятор генерирует жестко закодированный вызов другого метода.

В других языках вызов метода является «динамическим», что означает, что во время выполнения учитываются все типы актуальных действий. Методы, которые полиморфны в своих аргументах, называются «мультиметодами» (они полиморфны не только в классе, в котором они определены, но и в аргументах, следовательно, «мульти») (Редактировать: исправлены опечатки)

2 голосов
/ 13 мая 2011

Я думаю, что проблема где-то еще в вашем коде.Если вы попробуете этот пример, все будет работать как положено:

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

Не могли бы вы опубликовать полный пример?может быть, есть проблема с определениями классов ...

1 голос
/ 13 мая 2011

Как сказала Ангел О'Сфера, C # не имеет многократной отправки, однако вы можете реализовать двойную отправку, используя Шаблон посетителя.

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

1 голос
/ 13 мая 2011

Я прошу прощения за то, что не знал специфики , почему это происходит, но у меня есть идея, как обойти это.

Попробуйте сбросить перегрузку (LateSession, SessionViewModel) и учтите LateSession в перегрузке (Session, SessionViewModel), например:

private void StoreSessionSpecific(Session dbSession, SessionViewModel session )
{
   if (dbSession is LateSession) { 
      // handle as LateSession
   } else { 
      // handle as base-class Session
   }
}
0 голосов
/ 13 мая 2011

Какой тип dbSession после этого назначения? Я бы предположил, что это то, что вы ожидаете, но это может быть Session.

Отдельно, вам действительно нужно перегружать этот метод как дочерним, так и родительским классом? Это кажется странным случаем, когда вам понадобится и то, и другое, что может привести к путанице.

...