C# 运算符“is”参数

本文关键字:参数 is 运算符 | 更新日期: 2023-09-27 18:37:17

我正在开发一个小游戏来娱乐它,我偶然发现了一个与C#的is运算符混淆的时刻。这是代码:

public static InventorySlot FindSlotWithItem(this IInventory inventory, Type itemType)
{
    return inventory.InventorySlots.FirstOrDefault(t => t is itemType);
}

就目前而言,这段代码无法编译,因为我的Visual Studio告诉我找不到类型或命名空间名称"itemType"。我想知道为什么会这样,并在MSDN上寻找了一些信息。这是我发现的:

是(C# 参考): 检查对象是否与给定类型兼容。例如,下面的代码可以确定对象是 MyObject 类型的实例,还是派生自 MyObject 的类型

这些行让我更加困惑,因为我显然将对象作为第一个参数传递,将类型作为第二个参数传递。我知道这与编译器查找名为"itemType"的类型这一事实有关,但这并不完全是我想要的行为。

请告诉我为什么这样的语法不起作用,以及为什么"itemType"不被"is"运算符视为类型。

C# 运算符“is”参数

这里的问题是Type类的对象与对类的编译时常量引用不同。相反,Type对象只是封装类的 matadata 的对象,因此它们不能用于直接创建变量、调用静态成员、作为泛型传递或像实际类引用那样is调用。

话虽如此,上述所有操作都有仅使用元数据的解决方法。对于类型比较,请尝试

t => itemType.IsAssignableFrom(t.GetType());

这将检查"是否可以为itemType类型的变量分配类型t.GetType()的值" - 这不仅会检查类型,而且还会很好地接受多态类型而不会抱怨。

您可以执行以下操作之一:

public static InventorySlot FindItem<T>(this IInventory inventory)
{
    return inventory.InventorySlots.FirstOrDefault(t => t is T);
}

或者这个:

public static InventorySlot FindItem(this IInventory inventory, Type itemType)
{
    return inventory.InventorySlots.FirstOrDefault(t => itemType.IsAssignableFrom(t.GetType()));
}

你不能像这样检查对象的类型,你必须使用运算符的类型名称:

// doesn't work
t is itemType
//working
t is String

因此,正如@AmirPopovich建议的那样,您可以使用泛型方法,该方法可帮助您is运算符提供 Type:

public static InventorySlot FindItem<T>(this IInventory inventory)
{
    return inventory.InventorySlots.FirstOrDefault(t => t is T);
}