运行数组列表中包含的对象的成员函数

本文关键字:对象 函数 成员 包含 数组 列表 运行 | 更新日期: 2023-09-27 18:25:24

基本上,我有一个不同类型对象的数组列表,这些对象都有Draw()函数。我想使用一个循环来运行每个对象的绘制函数。但C#告诉我,类型"对象"没有这个函数。有没有一个低n00b的想法?

运行数组列表中包含的对象的成员函数

应该在接口中定义Draw方法:

public interface IDrawable 
{
    void Draw();
}

所有其他类(使用.Draw方法)都应该实现这个接口。您的列表应该是List<IDrawable>。然后,您可以简单地按预期对每个项目调用.Draw方法:

List<IDrawable> list = new ...;
foreach (var item in list) 
{
    item.Draw();
}

除非您正在使用。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();
}

它们都应该实现一个IDrawable接口。并且您的arraylist可能希望包含一个IDrawable列表,而不是对象列表。

如果它们共享一个公共接口,则可以强制转换为该接口。

如果类型的数量是已知且固定的,请尝试使用AS运算符强制转换为每个已知类型。

否则,你将不得不求助于反思,比如这个

for (i...){
    object oneObject = arrayList[i];
    Type objectType = oneObject.GetType();
    objectType.GetMethod("Draw").Invoke(oneObject, new object[0]);
}

但是,如果您需要求助于反射,这是一种巨大的代码气味,应该避免。

对于ArrayList,所有元素都存储为类型Object。要调用在另一个类型上定义的函数,首先需要将成员强制转换为该类型。

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>