2015-01-11 54 views
4

我正在爲它的樂趣開發一個小遊戲,我偶然發現了一個令人困惑的時刻,C#的操作符。下面是代碼: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'不被'is'操作符視爲一種類型。

回答

6

這裏的問題是,Type類的對象是不一樣的編譯時常引用的類。相反,Type對象只是封裝類的基礎數據的對象,因此它們不能用於直接創建變量,調用靜態成員,作爲泛型傳遞,或者以實際類引用可以調用的方式調用。

這就是說,所有上述操作都只有利用元數據的解決方法。對於類型比較,儘量

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

但第二個與第一個不一樣,因爲它不適用於itemType的子類。 –

+3

請注意,'GetType()== itemType'將直接比較類型的相等性,而不是可分配性/繼承性,因爲'is'運算符確實 - 參見'Type.IsAssignableFrom(Type)' – David

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