2011-05-13 54 views
9

的類型調用的最具體方法這裏總的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繼承會議)

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


} 
+0

是否有一個特定的原因,你輸入'var'而不是'LateSession'? – acron 2011-05-13 13:51:54

+8

@acron,什麼是不輸入'var'的原因? – detunized 2011-05-13 13:53:40

+0

@detunized,這只是我的看法,'var'是懶惰的,尤其是那時你像Saab一樣爲它分配一個特定的類型。爲什麼*不會*定義爲'LateSession'?事實上,這整個問題不是反對使用'var'的證明嗎? – acron 2011-05-13 13:59:35

回答

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

在第一個例子中,編譯器prettends不知道什麼實際類型「S的「並用Session參數硬編碼該方法的調用。 在第二個例子中,編譯器生成一個到另一個方法的硬編碼調用。

在其他語言中,方法調用是「動態的」,這意味着在運行時會考慮實際類型。在它們的參數上多態的方法被稱爲「multimethods」(它們不僅在它們被定義的類中是多態的,而且在參數上也是多元的),因此「多」)

+0

一個很好的解釋,我從來不知道這一點。進一步的谷歌搜索顯示,C#和Java都不允許多次調度,但是Lisp和Python都可以。 – Zruty 2011-05-13 14:01:42

+2

但實際上,在這種情況下,**應該**按預期工作,因爲該類型在編譯時已知,並且應該調用正確的重載。可能還有一些其他問題,從示例中未顯示出來...... – 2011-05-13 14:06:11

+0

該類型在編譯時不是「真正」已知的。考慮通過參數調用的變量。我只把「新」放在那裏,我們作爲讀者知道發生了什麼; D – 2011-05-16 15:31:12

0

那個作業後的dbSession是什麼類型?我會認爲這是你的期望,但它可能是Session

另外,你是否真的需要用子類和父類重載這個方法?這似乎是一個奇怪的情況,你會同時需要這兩個,並可能導致混淆。

+0

我把那個作爲一個例子。所以dbSession是LateSession類型的。在我的代碼運行時,我看到dbSession是LateSession類型,基類是Session。 我想這樣做,所以我對不同類型有不同的行爲。否則,我會訴諸超級討厭的開關。 – Saab 2011-05-13 13:55:50

1

我很抱歉不知道的具體情況爲什麼發生這種情況,但我有一個關於如何解決它的想法。

嘗試失去了(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 
    } 
} 
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(); 
    } 
} 

你能發佈一個完整的例子嗎?也許有類定義的問題...

相關問題