C#运营商'是'参数

时间:2015-01-11 15:55:22

标签: c# .net types operators

我正在开发一款有趣的小游戏,我偶然发现了一个令人困惑的时刻,C#是运营商。这是代码:

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'不被视为'是'操作

3 个答案:

答案 0 :(得分:6)

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

话虽如此,上述所有操作都只使用了元数据。对于类型比较,请尝试

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

这将检查"类型itemType的变量是否可以赋值t.GetType()" - 它不仅可以检查打字,还可以很好地接受多态类型而无需投诉。

答案 1 :(得分:5)

你可以这样做:

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()));
}

答案 2 :(得分:2)

您无法像这样检查对象的类型,您必须使用运营商的类型名称:

// 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);
}