2016-08-19 53 views
2

我想通過代理來處理實例,代理是類本身的一個屬性。委託的參數應該始終是實例本身(即使在派生類中也是如此!)。使用派生類類型作爲基類的通用動作的參數

查看下面的代碼。我知道代碼並沒有編譯,因爲我必須投入car1來輸入汽車,我正在尋找一個解決方案,而無需投射。

代碼

static void Main(string[] args) 
{ 
    var car = new Car(); 
    car.VehicleManipulator = car1 => car1.SomeInt++; 
    car.ManipulateVehicle(); 

    Console.WriteLine("end"); 
    Console.ReadLine(); 
} 

internal class Vehicle 
{ 
    public Action<Vehicle> VehicleManipulator { get; set; } 

    public void ManipulateVehicle() 
    { 
     this.VehicleManipulator(this); 
    } 
} 

internal class Car : Vehicle 
{ 
    public int SomeInt { get; set; } 
} 

編輯: 改變的代碼!

我的問題是,是否有一個很好的解決方案來處理所有這些只是在基類中,但在行動中我想使用派生類而不需要強制轉換。

+0

問題在哪裏?您可以使用[virtual](http://stackoverflow.com/q/8309419/1997232)方法,如果這是問題,則所有繼承的類都會覆蓋。 – Sinatr

+0

Car.VehicleManipulator操作爲空,您從未分配它,使其變爲虛擬並且編譯器將在派生類中尋找實現 –

+0

@ A.T。相反*表示*屬性被賦值,但該方法使用*基類的*屬性。這不是關於空值,它是關於繼承 –

回答

2

如果你想避免鑄造,使車輛通用,如:

class Vehicle<T> where T : Vehicle { 
    Action<T> ManipulateVehicle { get; set; } 
} 

class Car : Vehicle<Car> { 
    int SomeInt { get; set; } 
} 

它看起來有點怪異,但它意味着,如果你有車的情況下操縱適用於汽車,如果你有它適用於卡車等卡車。車輛應該可能是抽象的。

4

你就近了。您爲此行car.ManipulateVehicle();獲得NullReferenceException的原因是因爲VehicleManipulator操作爲空。

enter image description here

正如你看到的基類的VehicleManipulator屬性爲null。

現在,如果僅僅在你失敗的行的上方分配行爲,它怎麼能是空的?所以問題在於,在你的派生類中,你有一個新的不同的屬性,其名稱爲VehicleManipulator,它隱藏了基礎屬性。所以當你分配car.VehicleManipulator時,你實際上是在派生類中而不是在基類中分配屬性。

刪除從派生類它將工作。

如果由於我還不能理解的原因,您確實希望將屬性保留在派生類中,那麼在進行賦值時,可以指定您想要像這樣指定基類:

enter image description here

+0

@Snowcrack - 這是否闡明瞭會發生什麼並幫助您解決它? –

0

剛剛從汽車類中刪除該行代碼:

public Action<Car> VehicleManipulator { get; set; } 

ManipulateVehicle是一個基類的方法和被調用時它與VehicleManipulator炒菜鍋基座(未派生)類的屬性。

添加VehicleManipulator屬性派生類隱藏基屬性,並分配時 - 基礎屬性都有它的null默認值,因此NullReferenceException

我也建議關鍵字abstract添加到Vehicle的簽名,因爲它是一個純粹的抽象。沒有等類型,只有汽車,卡車一個不能創造只是汽車,摩托車等

因此,工作代碼可以是這樣的:

abstract internal class Vehicle 
{ 
    public virtual Action<Vehicle> VehicleManipulator { get; set; } 

    public void ManipulateVehicle() 
    { 
     this.VehicleManipulator(this); 
    } 
} 

internal class Car : Vehicle 
{ 
} 
相關問題