2013-08-22 13 views
0

我有以下幾點:在基類中使用一個覆蓋的屬性

class Info 
{ 
    public string str; 
}; 

class CarInfo : Info {} 

class InfoContainer 
{ 
    public virtual List<Info> info_list {get; set;} 
    public bool is_known(Info inf) 
    { 
     if (-1 == info_list.FindIndex(i => i.str == inf.str) return false; 
     return true; 
    } 
} 

class CarFleetInfo : InfoContainer 
{ 
    new public List<CarInfo> info_list; 
    CarFleetInfo() 
    { 
     info_list = new List<CarInfo>(); 
    } 
} 


Main() 
{ 
    CarInfo c = new CarInfo(); 
    Info i = new Info(); 
    c.is_known(i); 
} 

我有一個從Info繼承(如CarInfo)其他一些「特定信息」級,並從InfoContainer繼承幾類,這是每個覆蓋info_list與其他一些「具體信息」的對象列表。

現在,撥打c.is_known(i)的電話會引發異常,說info_list爲空。

+1

您的代碼無效,以開始。您無法聲明虛擬字段。 –

+0

你說得對。它假設是一個財產。 –

+1

和子類中的那個?請注意,即使你創建了一個屬性,它也不會重載基類,因爲你使用'new'而不是'override'。 –

回答

-2

基類的目的是提供將被覆蓋的函數和定義。重寫基類是沒有意義的。可能是打破語言的一個很好的練習,但總的來說,你正在編譯器中創建一個悖論和一個無限循環。 override屬性意味着預處理器的代碼應該優先運行,而不是它的基類操作。

但是,在大多數情況下,您仍應該調用基類操作,以確保繼承對象的所有字段和對象都被實例化並正確初始化。

+0

這不是很清楚,我覺得它可能是錯誤的,但我不清楚,我不知道。 – Bobson

+0

覆蓋其中的基類是毫無意義的。它在編譯器中創建無限遞歸。通常,您只會覆蓋從基類繼承的對象中的基類操作。如果它能夠編譯,覆蓋它自身內部的基類會創建無限遞歸。 這可能是也可能不是作者的意圖,但基於這是它看起來的標題。此外,所描繪的課程的目的不容易確定,我無法理解他想要做什麼。所以我只會脫離這個主題的標題。 –

0

您的問題是new public List<CarInfo> info_list;上的new關鍵字。在這種情況下,new的意思是「忽略我的基類提供的定義(如果有的話),並使用我自己的定義」。所以當你設置一個CarInfoinfo_list,你是而不是設置基地Infoinfo_list。然後,當您嘗試訪問作爲Info的一部分的info_list時,它爲空。

修復它的最好方法是取出CarInfoinfo_list,並簡單地使用基類的版本。這是正確方式做你在這裏試圖做的,雖然也有其他人可以使用。

0

你不是覆蓋info_list財產,你是影子。

要覆蓋屬性,您應該使用override關鍵字而不是new關鍵字,然後代碼將按預期工作。

當你爲該屬性設置影子時,子類將獲得它自己的屬性,並且該屬性具有相同的名稱,而基類不知道任何關於該屬性的內容。

0

您正在使用new屬性顯式隱藏其基類中的成員。由於List<Info>不是List<CarInfo>,因此使用override將無效。

而是考慮使用泛型:

class Info 
{ 
    public string Foo { get; set; } 
} 

class CarInfo : Info {} 

class InfoContainer<T> 
    where T: Info 
{ 
    public List<T> info_list { get; set; } 

    public bool is_known(T inf) 
    { 
     if (-1 == info_list.FindIndex(i => i.Foo == inf.Foo)) return false; 
     return true; 
    } 
} 

class CarFleetInfo : InfoContainer<CarInfo> 
{ 
} 
0

有兩個問題:

  1. 你應該重寫,而不是陰影
  2. 不能覆蓋的方法具有不同的簽名

    class Info { public string str; };

    class CarInfo : Info {} 
    
    class InfoContainer 
    { 
        public virtual List<Info> info_list {get; set;} 
        public bool is_known(Info inf) 
        { 
         if (!info_list.Exists(p => p.str == inf.str)) return false; 
         return true; 
        } 
    } 
    
    class CarFleetInfo : InfoContainer 
    { 
        public override List<Info> info_list { get; set; } 
    
        CarFleetInfo() 
        { 
         info_list = new List<Info>(); 
        } 
    } 
    

你不能讓公衆List<CarInfo>覆蓋公共List<Info>

0

我認爲你不能指定List<CarInfo>List<Info>,所以你不能覆蓋info_list的方式。要變通,您必須使用通用類,而不是定義如下:

class InfoContainer<T> where T : Info 
{ 
    public virtual List<T> info_list {get; set;} 
    public bool is_known(T inf) 
    { 
    if (-1 == info_list.FindIndex(i => i.str == inf.str) return false; 
    return true; 
    } 
} 
class CarFleetInfo<T> : InfoContainer<T> where T : CarInfo 
{ 
    public override List<T> info_list {get;set;} 
    public CarFleetInfo(){ 
    info_list = new List<T>(); 
    } 
}