如何在C#中的不同类的字典中存储不同类型的方法

时间:2017-12-05 21:05:27

标签: c#

我正在构建一个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"));
    }
}
}

2 个答案:

答案 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页之间会有什么不同,因为你在两种情况下使用相同的方法。