2010-07-25 38 views
2

我寫這個方法:這是泛型錯誤使用的例子嗎?

public IGamePlugin[,] GetTable<T>() 
    { 
     Type t = typeof(T); 

     if (t is IFixedElement) 
     { 
      return fixedElements; 
     } 
     else if (t is IFixedTile) 
     { 
      return fixedTiles; 
     } 
     else 
     { 
      throw new NotSupportedException("Type:" + t.ToString() + " is not supported"); 
     } 
    } 

而且我不是很確定,如果它不是泛型錯誤使用。我比使用一個簡單的參數(字符串或可能是類型)更好,因爲語法在調用端清晰。

您認爲如何?

回答

4

這確實應該是兩個獨立的功能,GetElementsTableGetTilesTable

要回答你的問題,這絕對是你濫用泛型的方式。但你說得對,使用參數也是不好的。

+0

爲什麼使用參數不好? – 2010-07-25 19:37:51

+0

使用參數可以是一個很好的解決方案,它取決於具體情況。 – MrFox 2010-07-25 19:38:09

+1

因爲一個功能應該有一個責任。這裏函數根據泛型來做兩個完全不同的事情,路徑之間沒有任何共享代碼,甚至在概念上也是如此,因此它們屬於不同的函數。使用參數而不是泛型類型不能解決違反單一責任原則的問題。 – 2010-07-25 19:41:47

2

這是一個不尋常的用法,當然;它不是真的使用T,除了typeof(T)。我可以看到,如果將它與通用約束相結合,它可能會更有用,但「原樣」我會試圖通過一個實例作爲參數。

順便說一句,is的用法在這裏不正確;你正在測試Type類型是否實現了IFixedTile等,這將從來沒有是真實的(除非你正在做一些非常不尋常的事情);您可能的意思是測試類型是否代表實現該接口。也許IsAssignableFrom

+0

在這個例子中,我想測試T是否真的是IFixedElement。我不想要實現IFixedElement接口的對象。 – 2010-07-25 19:38:42

+0

@MartyIX - 你想念我的觀點; 't'是'Type'類型的對象,而**從不**實現這些接口。我已經澄清了更新... – 2010-07-25 19:41:09

+0

@MartyIX:然後測試將是'if(typeof(T)== typeof(IFixedElement))'...但我覺得兩個函數更好。 – 2010-07-25 19:43:03

0

這取決於你是否要對類做其他事情?定義接口和類只是爲了做出選擇似乎有點浪費。如果您只需要在兩個狀態之間進行選擇,請使用枚舉:

public enum ElementType 
{ 
    FixedElements, FixedTiles 
} 

然後您可以要求提供ElementType參數。

+0

我沒有看到'GetTable(ElementType.FixedTiles)'在'GetTilesTable()'上的好處。也許如果這是一種虛擬方法,並且可能類型的集合各不相同,但不適用於這個問題。 – 2010-07-25 19:39:11

1

我同意本Voigt - 它應該是兩種不同的方法。

但實際上你的代碼不會工作,因爲t是Type object ant它沒有實現你的任何接口。相反,你應該使用t.GetInterface("IFixedElement") != null

+0

馬克已經指出了。感謝您的方法! – 2010-07-25 19:52:07

0

它看起來像你正在返回一個特定的二維數組取決於提供的類型。因此,您要查找的基本參數不是對象正在通過,而是類型。如果是這樣的話,爲什麼不簡單地聲明Dictionary<Type, IGamePlugin[,]>並從字典中獲得所需的價值?

我想這樣的:

// declare this somewhere earlier in the code... 
var plugInDictionary = new Dictionary<Type, IGamePlugin[,]>() 
{ 
    {typeof(IFixedElement), fixedElements}, 
    {typeof(IFixedTile), fixedTiles} 
} 
... 

// where you would normally call the method GetTable call this instead... 
var myGamePlugIn = plugInDictionary[typeof(myObject)]; 

使用字典的優點是,它比使用if塊更有活力,特別是因爲它可容納DI更容易比如果塊。這意味着,例如,您可以將上面的設置註冊到一個配置文件中,並且實際上只需編寫幾行代碼 - 其餘部分由DI框架處理。並不是說我爲你的項目提倡DI,但這是考慮到代碼靈活性時想到的一個例子。

+0

感謝您的解決方案!這是什麼意思「DI」? – 2010-07-25 20:21:38

+0

@MartyIX:依賴注入 – 2010-07-25 20:42:08