I am developing a small game for the fun of it and I stumbled upon a confusing moment with C#'s is operator. Here is the code:
public static InventorySlot FindSlotWithItem(this IInventory inventory, Type itemType)
{
return inventory.InventorySlots.FirstOrDefault(t => t is itemType);
}
As it stands, this code doesn't compile as my Visual Studio tells me that type or namespace name 'itemType' could not be found. I was wondering why that is and looked for a bit of information on MSDN. And here is what I found:
is (C# Reference): Checks if an object is compatible with a given type. For example, the following code can determine if an object is an instance of the MyObject type, or a type that derives from MyObject
And these lines got me even more confused as I am clearly passing an object as the first parameter and the type as the second. I understand that this is connected to the fact that compiler looks for a type called 'itemType', but this is not exactly the behavior I want.
Please tell me why such syntax is not working and why 'itemType' is not considered a type by 'is' operator.
The issue here is that the objects of the Type
class are not the same as the compile-time constant reference to a class. Instead, Type
objects are just objects encapsulating the matadata of a class, and they thus can't be used to directly create variables, call static members, pass as generics, or be called with is
the way an actual class reference can.
That being said, all the above operations have workarounds utilizing only the metadata. For type comparison, try
t => itemType.IsAssignableFrom(t.GetType());
This will check whether "a variable of type itemType
can be assigned a value of type t.GetType()
" - which will check not only for typing, but will also nicely accept polymorphic types without complaint.
You can do either this:
public static InventorySlot FindItem<T>(this IInventory inventory)
{
return inventory.InventorySlots.FirstOrDefault(t => t is T);
}
or this:
public static InventorySlot FindItem(this IInventory inventory, Type itemType)
{
return inventory.InventorySlots.FirstOrDefault(t => itemType.IsAssignableFrom(t.GetType()));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With