当前位置:  开发笔记 > 编程语言 > 正文

如何让这个重复的代码更优雅?

如何解决《如何让这个重复的代码更优雅?》经验,为你挑选了1个好方法。

我有下面这个重复的代码,我假设这可以合并,但如果你注意到每个字典是不同的通用字典:

dictionary1是类型的

Dictionary  

而dictionary2的类型是:

Dictionary

      DataTable dt = GetDataTable("CI");
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            DataRow dr = dt.Rows[i];
            int id = Convert.ToInt32(dr["id"]);
            string name = dr["name"].ToString();
            _dictionary1[id] = new ContinuousIntegrationSolution(){Name = name};
        }

        DataTable dt1 = GetDataTable("Bug_Tracking");

        for (int i = 0; i < dt1.Rows.Count; i++)
        {
            DataRow dr = dt1.Rows[i];
            int id = Convert.ToInt32(dr["id"]);
            string name = dr["name"].ToString();
            _dictionary2[id] = new BugTracker() { Name = name };
        }

        DataTable dt2 = GetDataTable("SDLC");

        for (int i = 0; i < dt2.Rows.Count; i++)
        {
            DataRow dr = dt2.Rows[i];
            int id = Convert.ToInt32(dr["id"]);
            string name = dr["name"].ToString();
            _dictionary3[id] = new SDLCProcess() { Name = name };
        }

注意:我修复了下面提到的一些拼写错误.



1> ShuggyCoUk..:
public interface INameable
{
    string Name {get;set;}
}

public static IDictionary ReadTable(string tableName)
    where T : INameable, new()
{
    DataTable dt = GetDataTable(tableName);
    var dictionary = new Dictionary();

    for (int i = 0; i < dt.Rows.Count; i++)
    {
        DataRow dr = dt.Rows[i];
        int id = Convert.ToInt32(dr["id"]);
        string name = dr["name"].ToString();
        dictionary[id] = new T() { Name = name };
    }
    return dictionary;
}

如果您拥有c#4.0动态,则可以避免因某些(轻微)类型安全性丢失而导致INameable

另一个类似于Hakon的答案,但没有暴露字典

public IDictionary ReadTable(
    string tableName, Action onName) 
    where T : new()
{
    var dictionary = new Dictionary();
    DataTable table = GetDataTable(tableName);
    foreach (DataRow row in table.Rows) 
    {
        int id = Convert.ToInt32(row["id"]);
        string name = row["name"].ToString();
        var t = new T();
        onName(t, name);
        dictionary[id] = t;
    }
    return dictionary;
}

然后像这样消耗:

var ci   = ReadTable("CI", 
              (t, name) => t.Name = name);  
var bt   = ReadTable("Bug_Tracking", 
              (t, name) => t.Name = name);  
var sdlc = ReadTable("SDLC", 
              (t, name) => t.Name = name);  

一种替代的,更灵活的方法,但由于类型推断在呼叫站点使用仍然相当简单,将是:

public IDictionary ReadTable(string tableName, Func create) 
{
    DataTable table = GetDataTable(tableName);
    var dictionary = new Dictionary()
    foreach (DataRow row in table.Rows) 
    {
        int id = Convert.ToInt32(row["id"]);
        string name = row["name"].ToString();
        dictionary[id] = create(name);
    }
    return dictionary;
}

然后像这样消耗:

var ci   = ReadTable("CI", 
               name => new ContinuousIntegrationSolution() {Name = name});  
var bt   = ReadTable("Bug_Tracking", 
               name => new BugTracker() {Name = name});
var sdlc = ReadTable("SDLC", 
               name => new SDLCProcess() {Name = name});

如果你采用lambda方法,我会建议后者.


我同意,但这将改变所提供的程序的语义(我承认一个微妙的变化)所以我倾向于在没有必要的时候纠正这些事情.
推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有