C# 运算符 'is' 参数

C# operator 'is' arguments

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

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

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

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

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

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

您可以这样做:

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 运算符提供类型:

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

这里的问题是 Type class 的对象与 class 的编译时常量引用不同。相反,Type 对象只是封装了 class 元数据的对象,因此它们不能用于直接创建变量、调用静态成员、作为泛型传递或用 [=13 调用=] 实际 class 引用的方式。

也就是说,上述所有操作都有仅使用元数据的解决方法。对于类型比较,try

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

这将检查是否 "a variable of type itemType can be assigned a value of type t.GetType()" - 这不仅会检查类型,还会很好地接受多态类型而不会抱怨。