基本上我有一個不同類型的對象的ArrayList,它們都具有Draw()函數。我想用循環來運行每個對象的繪圖函數。但C#告訴我,類型「對象」沒有這個功能。任何想法對於低n00b?運行包含在數組列表中的對象的成員函數?
回答
這Draw
方法應該在一個接口來定義:
public interface IDrawable
{
void Draw();
}
所有其他類(以.Draw
法)應實現此接口。而你的名單應該是List<IDrawable>
。然後,你可以簡單地調用每個項目的.Draw
方法預期:
List<IDrawable> list = new ...;
foreach (var item in list)
{
item.Draw();
}
他們都應該實現一個IDrawable接口。你的數組列表可能會包含一個IDrawable列表而不是對象。
除非你使用.NET 1.1,否則你不應該使用ArrayList
。
如果你在談論UI元素,他們都應該實現IDrawable
接口。如果它們是您的自定義類型,那麼您也應該在這些類上實現IDrawable
接口。然後您可以使用通用的List<T>
來存儲它們。
List<IDrawable> objects = new List<IDrawable>();
// Fill the list
// Iterate over each object and call Draw()
foreach(IDrawable obj in objects)
{
obj.Draw();
}
如果它們共享一個通用的接口,你可以到該接口。
如果類型的數量已知並且是固定的,請嘗試使用AS
運算符投射到每個已知類型。
否則,你就不得不求助於反射,這樣的事情
for (i...){
object oneObject = arrayList[i];
Type objectType = oneObject.GetType();
objectType.GetMethod("Draw").Invoke(oneObject, new object[0]);
}
但是如果你需要求助於的反映,是一個巨大的代碼的氣味,應該被避免。
隨着ArrayList
所有的元素被存儲爲類型Object
。要調用在antother類型上定義的函數,首先需要將成員轉換爲該類型。
class MyType {
public void Draw() {
...
}
}
for (int i = 0; i < arrayList.Count; i++) {
MyType current = (MyType)arrayList[i];
current.Draw();
}
此代碼只能但如果存儲在ArrayList
的對象轉換爲MyType
。如果您使用.Net 2.0或更高版本,則完全避免使用ArrayList
,而應使用List<MyType>
。這是一個強類型的集合,並且完全避免了演員的需要。
List<MyType> list = ...;
for (int i = 0; i < list.Count; i++) {
list[i].Draw();
}
如果您正在使用C#4或更好,你可以使用這個動態類型:
foreach (dynamic obj in arrayList)
obj.Draw();
這將在運行時失敗,如果你有一個對象,其類型缺少匹配Draw()
簽名。
如果您使用的是早期版本的C#,則可以使用反射。除此之外,你真的不應該使用ArrayList
,除非你被某些遺留庫強制使用。正如其他人所認爲的,更習慣的解決方案是擁有一個IDrawable
接口和一個List<IDrawable>
。
在任何情況下都不應該將此解決方案作爲首選。 – 2012-02-22 21:27:08
@KirkWoll我不同意。如果我無法控制arrayList或其內容的類型,例如,如果這些內容是通過調用傳統庫返回的,我會使用此解決方案。 – phoog 2012-02-22 21:31:42
我還沒有遇到使用第三方庫迫使我放棄類型安全的場景。有很多[設計模式](http://en.wikipedia.org/wiki/Adapter_pattern)可以解決這類問題,而無需放棄靜態類型系統。無論如何,我們幾乎不同意 - 我說這不應該成爲你的第一選擇,如果你能控制代碼。 – 2012-02-22 21:34:43
- 1. axis2包含列表的對象數組
- 2. LINQ - 按多個屬性對列表進行分組,並返回一個包含數組成員的對象
- 3. Sort Objective-c數組,其中包含包含數組的對象
- 4. 排序包含java中的對象的數組列表
- 5. Marshalling包含MarshalByRefObj成員的Serializable數組
- 6. 訪問數組中對象的成員函數
- 7. 在所有陣列成員上調用對象成員函數
- 8. 返回一個包含WCF服務列表成員的對象
- 9. 成員函數非對象
- 10. 具有鏈接列表成員的對象的析構函數
- 11. 如何使用函數列表指向矢量對象中的成員函數?
- 12. 如何使用構造函數初始化包含數組的對象列表
- 13. 通行證對象數組成員函數
- 14. 具有包含兩個整數成員對象的排序列表
- 15. 包含錶行值數組的SQL列
- 16. 中包含的對象作爲數組
- 17. 錯誤:調用一個成員函數包含()對數組的Symfony 3
- 18. 對象數組包含另一個數組的對象,需要通過包含數組的對象中的值對數組進行過濾
- 19. 如何將包含作爲數組的成員變量的對象轉換爲對象數組?
- 20. 在變更對象所在列表的列表中的每個對象上調用成員函數
- 21. 包含對象的ObservableCollection包含列表
- 22. 使用lambda函數合併包含不同對象的列表
- 23. 初始化包含其他對象數組的對象數組?
- 24. C++序列化包含其他對象數組的對象
- 25. 使用成員函數對類對象的數組進行排序
- 26. 包含含指針對象的對象的C++析構函數
- 27. 函數對象與僅包含標題的庫中的函數
- 28. 如何查找包含列成員的列數據對象名稱
- 29. PHP:如何將數組傳遞給對象的成員函數?
- 30. 在包含對象值的對象中創建一個數組
使用自.NET 2以來可用的通用集合。 – ChaosPandion 2012-02-22 21:24:51