我正在构建一个Windows应用程序,以便能够读取包含大量标记的txt文件,该标记解释了提供的信息类型。使用的标记看起来像#34; #FLAG xxx"其中xxx是检索到的信息。根据使用的标记,信息的处理方式不同,因此我需要不同的方法来提取它。
在我的程序中,我使用Dictionary来存储文件中可能包含的所有可能的标记变体,然后我读取文件中的每一行并比较字典中是否有匹配。就像现在一样,我硬编码要调用的方法,但觉得它必须是解决这个问题的愚蠢方法。我从另一个类(设置)加载Dictionaryn中包含的所有内容,这意味着我无法访问我在第一个类(Form1)中放置的方法。
我知道我在这里犯了很多错误,但我对C#很陌生,而且我自己也无法做出更好的解决方案。如何更好地解决这个问题。如果我不需要,我不想写很多if语句。
以下代码是我所写内容的向下版本。另外,阅读会很麻烦。是的,我删除了Excel导出部分,但希望你能看到我试图做的事情。
Forms1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace MarkupReader
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
OpenFileDialog ofd = new OpenFileDialog();
private void button1_Click(object sender, EventArgs e)
{
ofd.Filter = "File (*.txt)|*.txt|All files (*.*)|*.*";
ofd.Title = "Open file";
ofd.Multiselect = false;
if (ofd.ShowDialog() == DialogResult.OK)
{
StreamReader readFile = new StreamReader(File.OpenRead(ofd.FileName), Encoding.GetEncoding(437));
ExportFile(readFile);
readFile.Dispose();
}
}
private void ExportFile(StreamReader readFile)
{
Dictionary<string, Tuple<string, int, string>> markup = new Dictionary<string, Tuple<string, int, string>>();
readFile.DiscardBufferedData();
readFile.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);
Settings settings = new Settings();
settings.SetMarkup(markup);
string fileMarkup = "";
string fileMarkupValues = "";
string line = "";
while (line != null)
{
line = readFile.ReadLine();
if (line != null)
{
//Get markup
fileMarkup = line.Trim().Split(' ').First();
fileMarkupValues = line.Replace(fileMarkup, "");
if (markup.ContainsKey(fileMarkup))
{
/* markupItemX = X is content
* Item1 = User flag
* Item2 = Export to worksheet number
* Item3 = Extract method to call
* Item4 =
*/
//Export to excel sheet 1
if (markup[fileMarkup].Item2 == 1)
{
if (markup[fileMarkup].Item3 == "extractDataOne") ExtractMethodOne(fileMarkupValues);
if (markup[fileMarkup].Item3 == "extractDataTwo") ExtractMethodTwo(fileMarkupValues);
if (markup[fileMarkup].Item3 == "extractDataThree") ExtractMethodThree(fileMarkupValues);
if (markup[fileMarkup].Item3 == "extractDataFour") ExtractMethodFour(fileMarkupValues);
if (markup[fileMarkup].Item3 == "extractDataFive") ExtractMethodFive(fileMarkupValues);
}
//Export to excel sheet 2
if (markup[fileMarkup].Item2 == 2)
{
if (markup[fileMarkup].Item3 == "extractDataOne") ExtractMethodOne(fileMarkupValues);
if (markup[fileMarkup].Item3 == "extractDataTwo") ExtractMethodTwo(fileMarkupValues);
if (markup[fileMarkup].Item3 == "extractDataThree") ExtractMethodThree(fileMarkupValues);
if (markup[fileMarkup].Item3 == "extractDataFour") ExtractMethodFour(fileMarkupValues);
if (markup[fileMarkup].Item3 == "extractDataFive") ExtractMethodFive(fileMarkupValues);
}
}
}
}
}
public void ExtractMethodOne(string markupData)
{
//Extract stuff and write to Excel
}
public void ExtractMethodTwo(string markupData)
{
//Extract stuff and write to Excel
}
public void ExtractMethodThree(string markupData)
{
//Extract stuff and write to Excel
}
public void ExtractMethodFour(string markupData)
{
//Extract stuff and write to Excel
}
public void ExtractMethodFive(string markupData)
{
//Extract stuff and write to Excel
}
}
}
Setting.cs(它真的包含更多,这只是一个例子)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MarkupReader
{
class Settings
{
public void SetMarkup(Dictionary<string, Tuple<string, int, string>> markup)
{
int workSheet = 1;
markup.Add("#FLAG", new Tuple<string, int, string>("User flag", workSheet, "extractDataOne"));
markup.Add("#FORMAT", new Tuple<string, int, string>("User format", workSheet, "extractDataOne"));
markup.Add("#TYPE", new Tuple<string, int, string>("User type", workSheet, "extractDataOne"));
}
}
}
答案 0 :(得分:0)
从我当前的项目中提取
private static Dictionary<string, Func<DataObj, string>> s_FormulaMap =
new Dictionary<string, Func<DataObj>, string>> {
{ "home", d=>GetHome(d) },
{ "shell", d=>MakeupShell(d) },
{ "user", d=>d.Get("User") }
};
将文字映射到Func的。 funcs接受一个DataObj并返回一个字符串。 然后做
var func = s_FormulaMap[keyWord];
val = func(de);
答案 1 :(得分:0)
基于ExtractX
方法的签名(带有一个字符串参数的void),您可以执行以下操作:
// Static field or whatever you want
Dictionary<string, Action<string>> methods = new Dictionary<string, Action<string>>()
{
{ "extractDataOne", ExtractMethodOne },
{ "extractDataTwo", ExtractMethodTwo },
{ "extractDataThree", ExtractMethodThree },
{ "extractDataFour", ExtractMethodFour },
{ "extractDataFive", ExtractMethodFive },
};
// And then use it like this
methods[markup[fileMarkup].Item3].Invoke(fileMarkupValues);
虽然我不明白你在第1页和第2页之间会有什么不同,因为你在两种情况下使用相同的方法。