【问题标题】:Too many If statements?If语句太多?
【发布时间】:2014-05-22 23:34:05
【问题描述】:

我有一个类使用 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 语句使它更干净。
  • 你有没有想过使用map String -> Function?
  • @MikeStrobel 还有另一个用于“change_bank_details_policy”的公共字符串

标签: c# epplus


【解决方案1】:

你能创建一个将字符串和值映射在一起的Dictionary(键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 ]

【讨论】:

  • 我什至会选择直接从字典中获取正确值的自定义属性,以进一步简化代码及其访问方式。
  • 这绝对是完美的,除了我需要有一个外部 excel 文件,因为值,即这些政策编号会改变,需要由应用程序的用户更改。
  • 我是说,从外部 Excel 文件读取到内部字典(应该很简单),然后使用内部字典进行简单查找,无需大量 If 语句。
  • 哇,我是个白痴,对不起,如果您的意思是我只是遍历整个电子表格构建字典,然后有方法返回字典值,例如公共静态字符串,我认为这确实解决了我的问题GetChangeBankDetailsPolicy() { return my_dictionary["change_bank_details_policy"]; }
  • 我不清楚你代码中的细节......但基本大纲就在那里,如果你能将正确的键和值放入字典中。
【解决方案2】:

问题的根源在于您有大约 40 个变量,这是一个明确的code smell。例如,您应该考虑使用Dictionary 来存储它们 - 而不是大量使用变量。

Dictionary 正在从“键”映射到“值”。在您的情况下,它将从一个字符串映射到一个字符串(如果您确实需要一个字符串)。

【讨论】:

    【解决方案3】:

    之前已经提到过 Switch 语句,但 C# 中的一个漂亮特性是您可以将对变量的直接访问设置为只读,因此要回答您的第二个问题,您的变量可以具有以下语法:

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

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

    instance.configUserName = "Bob";
    

    可以在类成员代码中工作,但不能在用户代码中编译,同时:

    String bob = instance.configUserName;
    

    将在这两个地方编译。

    【讨论】:

    • 您忘记了它不会缩短代码。您需要两个独立的东西:一个用于存储数据的变量,以及一个用于定义如何访问它的属性。在您的代码示例中,您使用了两次相同的名称,这将不会编译(或无限循环,如果它编译)
    • 这很有趣,但我认为它不能解决我的问题的核心,即定义值的位置。
    【解决方案4】:

    以下代码不会覆盖未读值。如果源文件中不存在行,则不会丢失先前的值。我认为它在源文件内容上更防弹。

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多