Supondo que eu tenha as seguintes interfaces:
public interface IVehicle
{
ITrackInfo TrackInfo { get; set; }
void ShowInfo();
}
public interface ITrackInfo
{
int Length { get; set; }
}
Agora eu tenho essas classes implementandoITrackInfo
public class RailInfo : ITrackInfo
{
int Length { get; set;}
int SleeperSpacing { get; set; }
}
public class CanalInfo : ITrackInfo
{
int Length { get; set; }
decimal AverageDepth { get; set; }
}
public class RoadInfo : ITrackInfo
{
int Length { get; set; }
Color Colour { get; set; }
}
Mas com as classes que implementam IVehicle
, quero que elas tenham uma implementação específica de ITrackInfo
.
public class Train : IVehicle
{
RailInfo TrackInfo { get; set; }
public void ShowInfo() {
Console.WriteLine("Railway is {0}km long". TrackInfo.Length.ToString());
Console.WriteLine("Distance between sleepers is {0}cm", TrackInfo.SleeperSpacing);
}
}
public class Boat : IVehicle
{
CanalInfo TrackInfo { get; set; }
public void ShowInfo() {
Console.WriteLine("Canal is {0}km long". TrackInfo.Length.ToString());
Console.WriteLine("The average depth is {0}m", TrackInfo.AverageDepth.ToString("F2"));
}
}
public class Bus : IVehicle
{
RoadInfo TrackInfo { get; set; }
public void ShowInfo() {
Console.WriteLine("Road is {0}km long". TrackInfo.Length.ToString());
Console.WriteLine("The road is coloured {0}", TrackInfo.Colour.ToString());
}
}
Obviamente não posso escrever como mostrado acima - isso produz um erro de compilação nas IVehicle
implementações, pois a TrackInfo
propriedade deve ser especificada como ITrackInfo
.
Existe uma maneira de forçar implementações específicas ITrackInfo
para implementações específicas de IVehicle
?
Espero algo um pouco mais elegante do que apenas fazer um check-in ShowInfo()
:
var info = TrackInfo as RailInfo;
if (info == null)
{
throw new Exception("Incorrect track info");
}