我有一个文本文件,应该初始化我的对象,它是围绕基于组件的模型构建的,这是我第一次尝试使用数据驱动的方法,我不确定我是否正朝着正确的方向前进
我目前的文件看起来像这样
EliteGoblin.txt
@Goblin.txt
[general]
hp += 20
strength = 12
description = "A big menacing goblin"
tacticModifier += 1.3
[skills]
fireball
@符号表示在该点解析哪些其他文件 []中的名称与代码中的组件类相对应 在它们下面是如何配置它们
例如,hp += 20
会增加从goblin.txt获取的值并将其增加20等。
我的问题是我应该如何解析这个文件,是否有某种用C#构建的解析器?
我可以更改文档的格式以匹配已经在.net中支持的已定义格式吗?
我如何了解每个值的类型? INT /浮动/串
这看起来是否可行?
提前致谢,Xtapodi。
答案 0 :(得分:12)
删除平面文件并获取XML。绝对看看XML序列化。您可以简单地在C#中创建所有对象作为类,将它们序列化为XML,然后将它们重新加载到应用程序中,而不必担心解析平面文件。因为您的对象将充当XML的架构,所以您不必担心转换对象并编写大量的解析例程,.NET将为您处理它。你将挽救许多头痛。
例如,您可以将您的类重写为:
public class Monster
{
public GeneralInfo General {get; set;}
public SkillsInfo Skills {get; set;}
}
public class GeneralInfo
{
public int Hp {get; set;}
public string Description {get; set;}
public double TacticModifier {get; set;}
}
public class SkillsInfo
{
public string[] SkillTypes {get; set;}
}
...并且您的XML将被反序列化为类似......
<Monster>
<General>
<Hp>20</Hp>
<Description>A big menacing goblin</Description>
<TacticModifier>1.3</TacticModifier>
</General>
<SkillTypes>
<SkillType>Fireball</SkillType>
<SkillType>Water</SkillType>
</SkillTypes>
</Monster>
..我的一些类名,层次结构等可能是错误的,因为我真的很快就打了一遍,但你得到了序列化将如何工作的一般要点。
答案 1 :(得分:2)
您可能想要查看Sprache,这是一个可以通过Autofac创建者Nicholas Blumhardt创建DSL的.net库。来自谷歌网站:
Sprache是一个小型图书馆 直接在C#中构造解析器 代码。
这不是“工业实力” 框架 - 它适合某个地方 正则表达式和a之间 完整的工具集,如ANTLR。
用法与大多数解析器构建不同 框架,您直接使用Sprache 从您的程序代码,不需要 设置任何构建时代码 生成任务。 Sprache本身就是一个 单个小组件。
简单的解析器可能会解析序列 人物:
//解析任意数量的资本'A' 一行var parseA = Parse.Char( 'A')AtLeastOnce(); SPRACHE 提供了许多内置功能 可以制作更大解析器的函数 从较小的,通常可以通过 Linq查询理解:
解析器标识符= 来自Parse.Whitespace.Many()的领先 从Parse.Letter.Once()开始 来自Parse.LetterOrDigit.Many()中的休息 来自Parse.Whitespace.Many()中的尾随 选择新字符串(first.Concat(rest).ToArray());
var id = identifier.Parse(“abc123 “);
Assert.AreEqual(“abc123”,id);
该文章的链接构建了一个由简单文本文件驱动的问卷,其格式如下:
identification "Personal Details"
[
name "Full Name"
department "Department"
]
employment "Current Employer"
[
name "Your Employer"
contact "Contact Number"
#months "Total Months Employed"
]
答案 2 :(得分:1)
没有内置函数可以完全按照您的要求进行操作,但您可以轻松编写它。
void ParseLine(string charClass, string line) {
// your code to parse line here...
Console.WriteLine("{0} : {1}", charClass, line);
}
void ParseFile(string fileName) {
string currentClass = "";
using (StringReader sr = new StringReader(fileName)) {
string line = sr.ReadLine();
if (line[0] == '@') {
string embeddedFile = line.Substring(1);
ParseFile(embeddedFile);
}
else if (line[0] == '[') {
currentClass = line.Substring(2, line.Length - 2);
}
else ParseLine(currentClass, line);
}
}
答案 3 :(得分:0)
你想做的事情并不容易。特别是统计继承。
因此,除非您能找到一些现有的代码,否则我建议您从更简单的要求开始,以便稍后添加更多涉及的功能并逐步构建功能。