将switch语句移动到文本文件

时间:2014-10-09 22:27:36

标签: c# .net switch-statement

以下是我的情况每当我们向目录添加新产品时,我们需要将产品添加到此代码段并重新编译dll,然后将它们推送到所有服务器。

我希望能够做的只是在DLL然后读入的文本文件中添加一行。为了简单起见,文件将与DLL一起驻留在同一文件夹中#39; S。主要问题是有几个地方称这一切都在productId中传递,所以改变它是不可行的。

void AssignFunctions(int productId)
{
    switch (productId)
    {
        case 31:
            IsSpread = CalendarIsSpread;
            IsLeftPage = CalendarIsLeftPage;
            GetOppositePageNumber = GeneralGetOppositePageNumber;
            break;
        case 49:
        case 63:
        case 64:
        case 69:
        case 70:
        ...
        case 592: 
        case 630: 
        case 686: 
            IsSpread = NeverASpread;
            IsLeftPage = GeneralIsLeftPage;
            GetOppositePageNumber = GeneralGetOppositePageNumber;
            break;
        case 73:
            IsSpread = GeneralIsSpread;
            IsLeftPage = GeneralIsLeftPage;
            GetOppositePageNumber = GeneralGetOppositePageNumber;
            break;
        case 444:
        case 445:
            IsSpread = BookletIsSpread;
            IsLeftPage = BookletLeftPage;
            GetOppositePageNumber = BookletGetOppositePageNumber;
            break;
        default:
            IsSpread = GeneralIsSpread;
            IsLeftPage = GeneralIsLeftPage;
            GetOppositePageNumber = GeneralGetOppositePageNumber;
            break;
    }
}

另一种情况是采用productId并将其与文本文件进行比较,然后采取相应措施。在这种情况下,调用看起来像这样:

void AssignFunctions(int productId)
{
    //Do Something here to get the productSpreadType

    switch (productSpreadType)
    {
        case 1:
            IsSpread = CalendarIsSpread;
            IsLeftPage = CalendarIsLeftPage;
            GetOppositePageNumber = GeneralGetOppositePageNumber;
            break;
        case 2:
            IsSpread = NeverASpread;
            IsLeftPage = GeneralIsLeftPage;
            GetOppositePageNumber = GeneralGetOppositePageNumber;
            break;
        case 3:
            IsSpread = GeneralIsSpread;
            IsLeftPage = GeneralIsLeftPage;
            GetOppositePageNumber = GeneralGetOppositePageNumber;
            break;
        case 4:
            IsSpread = BookletIsSpread;
            IsLeftPage = BookletLeftPage;
            GetOppositePageNumber = BookletGetOppositePageNumber;
            break;
        default:
            IsSpread = GeneralIsSpread;
            IsLeftPage = GeneralIsLeftPage;
            GetOppositePageNumber = GeneralGetOppositePageNumber;
            break;
    }
}

在这种情况下,文本文件看起来像这样:

31 1
49 2
63 2
...
73 3
444 4

如果未列出productId,则只会执行默认操作。

.NET不是我的强项,每次添加新产品时都需要半天才能记住如何更新它。因为我是唯一一个在Windows上运行Visual Studio的人,所以任务总是落在我身上。除了必须进行此更改之外,我们不必触及代码库,因此不必每次都构建DLL并且能够通过确保任务的任务是很好的。这会更新给我们的一位初级开发人员,他们负责添加新产品。

3 个答案:

答案 0 :(得分:1)

C#是一种静态语言,不适用于您所建议的动态代码。 然而,我会考虑一种不同的设计,您可以从数据库中读取不同的类别,并将它们作为类别而不是具有相同处理的单个项目。 看起来你可以将很多这些组合在一起。

您还可以将配置文件视为类别的来源。

答案 1 :(得分:0)

你可以使用一点反射魔法:

using System;
using System.Linq;
using System.Reflection;

public class Program
{
    public static void Main()
    {   
        // Test Data
        DoProduct(31);      
        DoProduct(63);  
        DoProduct(49);
        DoProduct(49);
        DoProduct(61);
    }

    public static void DoProduct(int productId)
    {
        string data = "";
        bool methodExecuted = false;

        // I am loading the string "data" with test data for simplicity.
        // In real life, you'll load this from your file intead.
        data = data + "31 MyFirstFunction" + Environment.NewLine;
        data = data + "49 MySecondFunction" + Environment.NewLine;
        data = data + "63 MyThirdFunction" + Environment.NewLine;

        foreach (string str in data.Replace(Environment.NewLine, "\n").Replace('\r', '\n').Split('\n'))
        {
            if (string.IsNullOrEmpty(str))
                continue;

            int pid = int.Parse(str.Split(' ')[0]);
            string func = str.Split(' ')[1];

            if (pid != productId)
                continue;

            Type type = typeof(Program);

            MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);

            MethodInfo method = methods.FirstOrDefault(z => z.Name.Equals(func));
            if (method == null) {
                continue;
            }

            method.Invoke(null, null);  
            methodExecuted = true;
        }

        if (!methodExecuted)
        {
            MyDefaultFunction();
        }
    }

    public static void MyFirstFunction() 
    {
        Console.WriteLine("This is MyFirstFunction()!");
    }

    public static void MySecondFunction() 
    {
        Console.WriteLine("This is MySecondFunction()!");
    }

    public static void MyThirdFunction() 
    {
        Console.WriteLine("This is MyThirdFunction()!");
    }

    public static void MyDefaultFunction() 
    {
        Console.WriteLine("This is MyDefaultFunction()!");
    }
}

这将允许您创建一个文本文件,如下所示:

31 MyFunction
63 AnotherFunction
...

使用反射,每次传入产品ID时,它都会执行正确的功能。如果产品ID不在文本文件中,它将调用默认函数。

以下是其中的一个小提琴:https://dotnetfiddle.net/7Atpq7

答案 2 :(得分:0)

如果您真的必须使用文本文件,可以使用结构将其加载到多值字典中,然后对该字典执行搜索

在名为test.txt的文本文件中假设以下测试数据:

1,value1,value2
2,value1,value2
...
你可以这样做:

class Program
{
    // declare test data
    public static int[] _products = new int[] { 1, 2, 3, 4, 5 };

    // Searchable value dictionary to be filled by file
    static Dictionary<int,Values> d = new Dictionary<int,Values>();      
    static void Main(string[] args)
    {
        // Read the file line by line into the dictionary          
        string line;
        System.IO.StreamReader file =
           new System.IO.StreamReader("c:\\test\\test.txt");
        while ((line = file.ReadLine()) != null)
        {
            string[] values = line.Split(',');
            int productId = int.Parse(values[0]);
            Values v = new Values();
            v.Value1 = values[1];
            v.Value2 = values[2];

            d.Add(productId, v);
        }
        file.Close();

        // check our loaded config file
        foreach (int p in _products)
        {

            if (d.Keys.Contains(p))
            {
                // we've found a match in the file
                // your logic goes here!
            }
            else
            {
                // no match was found
                // handle missing data
            }
        }

    }

    // struct to hold your data from text file
    struct Values
    {
        public string Value1;
        public string Value2;
    }

}