【问题标题】:C# operator 'is' argumentsC# 运算符“是”参数
【发布时间】:2015-03-09 10:55:32
【问题描述】:

我正在开发一个有趣的小游戏,但我偶然发现了 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# .net types operators


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 这就是我真正想知道的。感谢您的回答。
    【解决方案2】:

    您可以这样做:

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

    【讨论】:

    • 但第二个与第一个不同,因为它不适用于 itemType 的子类。
    • 请注意,GetType() == itemType 将直接比较类型是否相等,而不是像 is 运算符那样用于可分配性/继承性 - 请参阅 Type.IsAssignableFrom(Type)
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2019-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-30
      • 2015-07-29
      • 2012-04-23
      • 2017-11-18
      • 1970-01-01
      相关资源
      最近更新 更多