我需要一种简单的方法来调用类中某种类型的所有字段的特定方法。 (适用于C#/ Unity3D)
示例:
public class Item{
public void Update(){
}
//....
}
public class Container{
Item a = new Item();
Item b = new Item();
Item c = new Item();//etc
public void UpdateAllItems();//<-- calls Update for a, b, c
}
限制:
Item
s不应明确存储对Container
的任何引用。它不应该Container
作为构造函数参数。Item
应为普通字段/变量。 (意味着用数组或者哈希替换它们不是一个好主意。为每个项目制作一个属性也不是一个好主意。)Item
或删除其中一些,我不需要在任何地方修改我的代码。因此,a.Update(); b.Update();
不是解决方案。 magicInternalContainer.Add(a); ... foreach(var item in magicInternalContaier)
也不合适。Item
不应来自MonoBehavior
或Component
。它是一个轻量级的对象。其他信息:
Item
的类型是已知的,不会改变;他们没有任何虚拟方法。Container
个对象,每个对象10-20 Item
,每秒30-60次调用UpdateAllItems
,最有可能在单个线程中。 Item
不会在运行时动态添加或删除。么?看起来Type.GetFields
是可行的方式,但似乎这会使用反射,人们会警告“反射很慢!”到处都是。或者,我需要用HashSet
替换变量,添加几个包装器并使用一些Enum
id来解决这些项目(在这种情况下我需要保持统一序列化,因为统一不会序列化泛型,无需额外帮助)。
这样做的正确方法是什么?
答案 0 :(得分:2)
好吧,既然你写了
Items
不会在运行时动态添加或删除。
我建议创建另一个将成为项集合的字段,并使用反射将其填充到容器类的构造函数中。
然后,在UpdateAllItems()
方法中,您可以迭代此集合并执行您想要的任何操作。
通过这种方式,您无需在添加或删除项目时更改代码中的任何内容,您无需担心反射性能,因为反射过程仅针对每个容器运行一次,并且您没有任何限制Item的类型,接受一个你无法避免的限制,即它有一个Update()
方法。