太多的If语句?

3

我有一个使用EPPlus从电子表格中读取文本的类。它能够运行并且完全满足我的需求,但我觉得我的方法不太好,但是我无法想到一个更少硬编码、使用更少if语句的替代方案。 这个类包含常量,比如:

private static string configUserName;
private static string configPassword;
private static string configUrl;
private static string configDatabase;
//etc

这里大约有40个。该类循环读取电子表格中的所有值,检查它所匹配的值:

int i = 1;
object isRow = currentWorksheet.Cells[i, 1].Value;
while (isRow != null)
{
if (isRow.ToString().Trim().Equals("change_bank_details_policy"))
     {
        if (currentWorksheet.Cells[i, 2].Value != null)
        {
         change_bank_details_policy =c currentWorksheet.Cells[i,2].Value.ToString().Trim();
        }
     }
else if //etc 40 more if statements

由于这些值是私有的,所以有40种方法,例如:
public static string GetConfigUserName()
    {
        return configUserName;
    }

一定有更好的方法来做这件事吧?电子表格看起来像这样:

change_bank_details_policy,11459676
change_DD_date_policy,11441975
[40 more rows....]

你可以使用 switch 语句使代码更加简洁。 - IllusiveBrian
1
你有没有考虑过使用一个映射 String -> Function? - Niklas B.
@MikeStrobel 还有一个名为“change_bank_details_policy”的公共字符串。 - Ben
4个回答

4

你能否制作一个键为 String,值为 Int字典,将字符串和值进行映射?

逐行读取 Excel 表格,以建立字典。
然后使用字典来设置相应的变量。

最终,你的字典应该如下所示:

        KEY                     VALUE
============================|========
change_bank_details_policy  |11459676
change_DD_date_policy       |11441975

在构建字典后,您只需执行以下操作:

change_bank_details_policy = my_dictionary["change_bank_details_policy"];

我认为大纲会是这样的:

Dictionary<String, UInt32> myDict = new Dictionary<String, UInt32>();

object isRow = currentWorksheet.Cells[i, 1].Value;
while (isRow != null)
{
    myDict.Add(isRow.ToString().Trim(), currentWorksheet.Cells[i,2].Value);
    // Go get the next Row.... details are up to you.
}

change_bank_details_policy  = myDict["change_bank_details_policy"]; // Look up this key in the dictionary to get this integer.... 
change_DD_date_policy       = myDict["change_DD_date_policy"];
// [... repeat 40 more times ... but no If statements ]

我甚至会选择一个自定义属性,直接从字典中获取正确的值,以进一步简化代码和访问方式。 - Flater
这本来是非常完美的,但问题在于我需要一个外部的Excel文件,因为数值,比如那些保单号码,会发生变化,需要由应用程序的用户进行更改。 - Ben
我是说,从外部的 Excel 文件中读取并存储到内部字典(应该很简单),然后使用内部字典进行简单查找,而无需大量使用 If 语句。 - abelenky
哇,我真是个白痴,抱歉。如果你的意思是我只需循环整个电子表格构建一个字典,然后有方法返回字典值,那么我认为这绝对解决了我的问题。例如:public static string GetChangeBankDetailsPolicy() { return my_dictionary["change_bank_details_policy"]; } - Ben
我对你的代码细节不是很清楚......但基本的轮廓已经在那里了,如果你能把正确的键和值放入字典中。 - abelenky
是的,我认为字典是完美的解决方案,谢谢。 - Ben

2
问题的根源在于您有约40个变量,这是明显的代码异味。您应该考虑使用一个字典(Dictionary),例如将它们存储起来,而不是广泛使用变量。
字典是从“键”到“值”的映射。在您的情况下,它将从字符串映射到字符串(如果您确实需要一个字符串)。

0

虽然已经提到了Switch语句,但C#中一个很棒的特性是你可以将变量设置为只读的直接访问方式,因此回答你的第二个问题,你的变量可以具有以下语法:

private static string configUserName
{
    public get;
    private set;
}

这将允许您的类成员直接访问变量,但如果用户尝试直接写入它,则会导致编译器错误(但如果他们尝试读取它,则不会),例如:

instance.configUserName = "Bob";

这将在类成员代码中工作,但不会在用户代码中编译,而:

String bob = instance.configUserName;

可以在两个地方编译。


你忘记了这样做并不能缩短代码。你需要两个单独的东西:一个变量来存储数据,和一个属性来定义如何访问它。在你的代码示例中,你使用了相同的名称两次,这将无法编译(或者如果编译成功会导致无限循环)。 - Flater
这很有趣,但我认为它并没有回答我的核心问题,即值的定义在哪里。 - Ben

0
以下代码不会覆盖未读取的值。如果源文件中不存在某一行,则先前的值不会丢失。我认为这样更加适用于源文件内容。
var dict = new Dictionary<string, Action<long>>();
dict.Add("change_bank_details_policy", v => change_bank_details_policy = v);
// 40 of these, no choice

int i = 1;
object isRow = currentWorksheet.Cells[i, 1].Value;
while (isRow != null)
{
    string rowTitle = isRow.ToString().Trim();
    if (dict.ContainsKey(rowTitle))
    {
        // Or parse it or whatever you have to do to handle the cell value type
        long rowValue = currentWorksheet.Cells[i,2].Value; 
        dict[rowtitle](rowValue);
    }

    isRow = currentWorksheet.Cells[++i, 1].Value;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接