我正在尝试用C#编写一个简单的角色扮演游戏,以便更熟悉该语言。
我有一个类从CSV文件加载数据,创建一个对象,并将其放在字典中。因为游戏的每个方面都有不同的数据(项目,演员,技能等),所以我将每个方面都设置为一个类,但这需要我为每个方面重新实现一个Load()方法。在做了5到6次之后,我想知道是否有更好的方法来实现它。
基本上,我想要做的是解析包含标题的CSV的第一行,并将它们用作类变量名。目前,它们是作为字典关系实现的,所以我会做SomeClassInstance.dict [“id”],我最好输入SomeClassInstance.id,它完全是从文件内容生成的。
这是一件事吗?我该怎么做?
答案 0 :(得分:7)
您需要阅读serialization - 而不是将文件保存在CSV文件中,您可以将它们以序列化格式存储,然后将直接加载到所需类型中。
您只需要几种方法来序列化和反序列化。
我建议阅读:
上面的链接是针对不同的序列化程序(我确实留下了一些 - 知道的任何人,如果你知道有一个好的序列化程序,请添加) - 阅读,查看他们的API,玩它们和看看他们的磁盘格式并做出决定。
答案 1 :(得分:7)
如果你坚持使用当前的设计(CSV +字典),你可以使用ExpandoObject类来获得你想要的东西,创建一个简单的工厂类:
public static class ObjectFactory
{
public static dynamic CreateInstance(Dictionary<string, string> objectFromFile)
{
dynamic instance = new ExpandoObject();
var instanceDict = (IDictionary<string, object>)instance;
foreach (var pair in objectFromFile)
{
instanceDict.Add(pair.Key, pair.Value);
}
return instance;
}
}
这个工厂将创建你给它的任何字典的对象实例,即只创建一个方法来创建所有不同类型的对象。像这样使用它:
// Simulating load of dictionary from file
var actorFromFile = new Dictionary<string, string>();
actorFromFile.Add("Id", "1");
actorFromFile.Add("Age", "37");
actorFromFile.Add("Name", "Angelina Jolie");
// Instantiate dynamically
dynamic actor = ObjectFactory.CreateInstance(actorFromFile);
// Test using properties
Console.WriteLine("Actor.Id = " + actor.Id +
" Name = " + actor.Name +
" Age = " + actor.Age);
Console.ReadLine();
希望这会有所帮助。 (是的,她出生于1975年)
答案 2 :(得分:1)
从DynamicObject派生并覆盖TryGetMember
,以便它返回相应的字典条目。正是微软在MVC 3的ViewBag中所做的。
示例用法(如果派生类型名为CsvBag
):
dynamic bag = new CsvBag(csvFileStream);
_monitor.Monster.LookUp(*bag.Id*).Attack(player); // whatever..
答案 3 :(得分:0)
为什么不创建一个负责读取数据和返回指定对象实例的管理器对象?类似的东西:
var actors = ActorsLoader.Load("actors.cvs");
其中ActorsLoader.Load可以实现为:
IEnumerable<Actor> Load( string fileName )
{
//1. reading each line (each line = new actor) & creating actor object
//2. adding created actor object to a collection
//3. returning back a collection
}
我假设每种类型的游戏内对象都存储在不同的文件中(因此你有:actors.csv,items.csv,skills.csv等。)