Reputation: 1293
I got an abstract Room with multiple child classes. Some of those childs have a property MaximumCapacity
. When anything enters a room, I want it to check if that Room has the property, and if so, what it is. I could easily make it using a switch case, but I'd rather not (lots of (repetitive) code).
Only two imporant properties:
MaximumCapacity
: Maximum capacity of the Room, stored in some of the different type of roomsCurrentPosition
: Room stored on the object that wants to enter the Room.This is what I currently have:
// HOW :: Store type of Room in order for me to cast with it.
// My Attempt:
Type T = CurrentPosition.GetType(); // Get the type of the Room
// The following doesn't work:
// Build-time exception: "T is used as a variable but is a type"
if ((CurrentPosition as T).GetProperty("Capacity") != null)
{
// Check capacity and enter Room.
}
I've tried doing the if (int.Parse(CurrentPosition.GetType().GetProperty("MaximumCapacity")) > [number])
But this gives a Can't convert type PropertyInfo to Int
. This makes me believe I still have to cast the Room to its clild (I think) in order to check the capacity.
How do I do this?
Upvotes: 0
Views: 110
Reputation: 1066
public abstract class Room
{
public abstract void BookTheRoom();
}
interface IMaximumCapacity
{
int MaximumCapacity { get; set; }
}
public class StorageRoom : Room
{
public override void BookTheRoom()
{
Console.WriteLine("Storage room booked to store the items.");
}
}
public class TwinSharingRoom : Room,IMaximumCapacity
{
public TwinSharingRoom(int capacity)
{
MaximumCapacity = capacity;
}
public int MaximumCapacity { get; set; }
public override void BookTheRoom()
{
Console.WriteLine("Twinsharing room booked.");
}
}
public class SingleSharingRoom : Room, IMaximumCapacity
{
public SingleSharingRoom(int capacity)
{
MaximumCapacity = capacity;
}
public int MaximumCapacity { get; set; }
public override void BookTheRoom()
{
Console.WriteLine("Single sharing room booked.");
}
}
And you can use this as
class Program
{
static void Main(string[] args)
{
var listOfRooms = new List<Room>() { new SingleSharingRoom(1), new StorageRoom(), new TwinSharingRoom(2) };
foreach(var room in listOfRooms)
{
if(room is IMaximumCapacity)
{
room.BookTheRoom();
}
}
}
}
Upvotes: -1
Reputation: 32445
You can do it without type checking.
Change type of MaxCapacity
to nullable and make all rooms to have this property.
Then you can simply does room have value of maximum capacity
if (room.MaxCapacity.HasValue)
{
// do you logic
}
You can do it in more object-oriented way, move logic to the room object to decide is somebody allowed to enter a room
if (room.AllowedFor(player))
{
// do your logic
}
Then rooms which have MaxCapacity will check for that, rooms which hasn't will always return false.
Upvotes: -1
Reputation: 81493
Sounds like a job for an interface
and Composition. This way you can check if your rooms support your various functionality
Given
public interface IMaximumCapacity
{
int MaximumCapacity { get; set; }
}
public class BaseRoom
{
}
public class DerivedRoom : BaseRoom, IMaximumCapacity
{
public int MaximumCapacity { get; set; }
}
Method
public static bool GetMaximumCapacity(BaseRoom room, out int maximumCapacity)
{
maximumCapacity = 0;
if (room is IMaximumCapacity capcityRoom)
{
maximumCapacity = capcityRoom.MaximumCapacity;
return true;
}
return false;
}
Usage
if(GetMaximumCapacity(someRoom,out var max)
{
// yay, do something with max
}
Upvotes: 4