C# 在C语言中创建动态变量名#

C# 在C语言中创建动态变量名#,c#,design-patterns,dynamic,csv,C#,Design Patterns,Dynamic,Csv,我正试图用C语言编写一个简单的角色扮演游戏,以便更加熟悉这门语言 我有一个类,它从CSV文件加载数据,创建一个对象,并将其放入字典中。因为游戏的每个方面都有不同的数据(项目、参与者、技能等),所以我将它们都设置为一个类,但这需要我为每个类重新实现Load()方法。在做了5到6次之后,我想知道是否有更好的方法来实现这一点 基本上,我想做的是解析CSV的第一行,它包含头,并使用这些作为类变量名。目前,它们是作为字典关系实现的,因此我将执行SomeClassInstance.dict[“id”],理想

我正试图用C语言编写一个简单的角色扮演游戏,以便更加熟悉这门语言

我有一个类,它从CSV文件加载数据,创建一个对象,并将其放入字典中。因为游戏的每个方面都有不同的数据(项目、参与者、技能等),所以我将它们都设置为一个类,但这需要我为每个类重新实现Load()方法。在做了5到6次之后,我想知道是否有更好的方法来实现这一点

基本上,我想做的是解析CSV的第一行,它包含头,并使用这些作为类变量名。目前,它们是作为字典关系实现的,因此我将执行SomeClassInstance.dict[“id”],理想情况下,我将键入SomeClassInstance.id,它完全由文件内容生成

这是一件事吗?如何做到这一点?

您需要仔细阅读—您可以将文件以序列化格式存储并直接加载到所需类型,而不是将其保存在CSV文件中

您只需要几个方法来序列化和反序列化

我建议阅读以下内容:

上面的链接指向不同的序列化程序(我当然省略了一些-任何人都知道,如果你知道有一个好的序列化程序,请添加)-通读,查看他们的API,使用它们,查看它们的磁盘格式,然后做出决定。

从TryGetMember派生并覆盖它,以便它返回适当的字典条目。这正是微软在MVC3的ViewBag中所做的。 用法示例(如果您的派生类型名为
CsvBag
):


为什么不创建一个负责读取数据和返回指定对象实例的管理器对象呢?比如:

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
}
IEnumerable加载(字符串文件名)
{
//1.阅读每一行(每一行=新参与者)并创建参与者对象
//2.将创建的actor对象添加到集合中
//3.退回收藏
}

我假设每种类型的游戏内对象都存储在单独的文件中(因此您有:actors.csv、items.csv、skills.csv等)

如果您坚持当前的设计(csv+字典),您可以使用ExpandoObject类来获取所需的内容,创建一个简单的factory类:

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;
    }
}
公共静态类ObjectFactory
{
公共静态动态CreateInstance(Dictionary objectFromFile)
{
动态实例=新的ExpandooObject();
var instanceDict=(IDictionary)实例;
foreach(objectFromFile中的变量对)
{
instanceDict.Add(pair.Key,pair.Value);
}
返回实例;
}
}
这个工厂将为您提供的任何字典创建一个对象实例,即只使用一种方法来创建所有不同类型的对象。像这样使用它:

   // 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();
//模拟从文件加载字典
var actorFromFile=new Dictionary();
添加(“Id”,“1”);
添加(“年龄”,“37”);
Add(“Name”,“Angelina Jolie”);
//动态实例化
dynamic actor=ObjectFactory.CreateInstance(actorFromFile);
//使用属性进行测试
Console.WriteLine(“Actor.Id=“+Actor.Id+
“Name=“+actor.Name+
“年龄=”+演员年龄);
Console.ReadLine();

希望这有帮助。(是的,她出生于1975年)

您可以使用反射来迭代类属性,测试属性的名称是否与CSV列的名称匹配,然后设置值。也许AutoMapper能帮上忙,但我不确定,你必须读一点关于它的书。不要为了简化持久性而在你的设计中弄糟@这导致了一些非常丑陋的代码:@James(1)丑陋的代码并不一定是坏代码。(2) 无论如何,它可以被改写成更漂亮的。(3) 当有人问问题时,我不打算改变情况。如果OP是使用CSV存储数据,那么,请继续,让我们关注这个问题。我问他“有更好的持久性方法吗?”,事情会有很大的不同,这正是我所拥有的(抱歉,如果我的专栏文章对此含糊不清)。实际上是ActorData,它包含一个。但是,加载构造函数是不同的。。。我的不是数不清的,只是一个公共空间。啊,对不起,误会了。所以,您实际上想要做的是完全摆脱序列化/反序列化代码?如果您希望有一些自动反序列化机制,那么查看ServiceStack使用的cvs反序列化程序可能会有所帮助?我相信那可能是我想要的。。。我基本上希望使用文件中的数据动态创建一个类。比如,它的成员将完全由文件决定。由于您的答案和其他一些人也提到了序列化,我想我应该进一步阅读。我认为您不能序列化/反序列化动态对象,您必须创建常规的非动态类才能使其工作。这非常有趣。我喜欢这个主意,它似乎简化了一些事情。
   // 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();