这是一个普遍的问题,我确信它已经解决了。
我有几个类(实体系统的组件),我想保存对文件(字符串或标志)中的类的某种引用,作为保存/加载系统的一部分。但是我希望能够随着时间的推移更改C#中的类的名称,并让它在下次自动重建正确的数据,而无需手动迁移数据。
目前我认为有一些方法可以自动完成,假设C#中所有引用的类都不会立即更改。我可以做字符串检查以消除可以解决的引用 - 然后显示一个UI弹出窗口来解决类似“哦,类Renderable已被更改,看起来Model的级别数据都指向这个,是吗?同一个班级?“我还可以使用Reflection查找函数名来构建相关类的“元数据配置文件”(区别于其名称标签),因此数据问题与GetType()。GUID或其他(初始化顺序?)无关。
如果我创建一些简单类型的数据库,那么将在第一个会话中生成标志值,然后在实际级别文件中查找并重新调整该特定级别文件..但这是它变得复杂的地方不好或有帮助。如果数据库文件丢失怎么办,加载级别文件时要解决200多种类型。
也许有一种更简单的方法。但就信息而言,只有cpu可能知道的实际类成员/字段,而没有明确指定和关注它。没有办法在这种数据问题上引发错误,没有验证检查。
我的一个想法是在定义类时使用互斥标签 - 强制它们使用模板参数T继承IDummy,其中T来自更多虚拟接口标签的列表,因此您可以选择类似于枚举条目的内容然后,如果类定义和类功能之间没有一致的映射(独立于其名称标签),则将其添加到字典(类型为键)以抛出更多错误以防止程序运行。然后,如果我想永久删除数据中的一个类 - 我只是将其“标签”列入黑名单。
我通过依赖于C#Reflection / metadata的模板技巧来完成所有这些工作。这是可能的,我知道是。
对于每个轻量级对象(实体),存储的所有内容都是id和flags值。
答案 0 :(得分:0)
使用Reflection你可以深入到任何程序集中并提取你想要的任何东西,这是一个提取ClassNames的例子。
var asm = Assembly.Load("Some.Assembly.Name");
var nameSpace = "Some.Namespace.Name";
var classes = asm.GetTypes().Where(p =>
p.Namespace == nameSpace &&
p.Name.Contains("ClassNameFilter")
).ToList();
答案 1 :(得分:0)
好的,我现在要做的是"脏"解决方案,但它是一丝不苟的人可以忍受的事情之一。
我只需添加一个独立于会话/标签的标识符。我打算使用一个看起来更清晰的模板参数..但我需要的是指定1,2或3等作为我想要区分的类的某种编译时ID(这些是索引到查找实际使用的bitflag值)
所以在类的第一行,我现在为类型id添加一个静态int。还有很多东西(模板基类,单例,初始化顺序黑客),但它至少现在很简洁。唯一的问题是我必须为每个班级指定一个数字。 (程序绝对必须知道独立于类名)。
元数据的想法是一个糟糕的主意,因为如果我想克隆一个类/组件,那么就无法正确地区分它(除了类型名称之外)。所以也许它可以奏效。
我不想涉及一个"数据库" (一个文本文件映射可以做 - 它从编译器的命名顺序中逃避初始化顺序)这可能是一个好主意,以避免它,只是为了那些极端情况(我的1000个游戏对象的数据库)想突然改变所有的班级名称)
这只是一个固有的信息问题。几乎唯一的解决方案是明确它所在的类(在所有其他上下文之外)并为重复的类型id抛出错误。
但是,我们不能推断,当有关数据的某些事情发生变化时,程序的行为。程序仍然可以找出什么是什么..除了你有一个组件类的情况与另一个组件类具有完全相同的字段和成员,所以它们都会看起来相同"除了类名,我们在解析它是什么类时不能依赖它。 (在我可以随时改变的情况下)。