0

我创建了一个库函数,并希望添加一个重载,它使用附加参数执行非常相似的操作。现有代码如下所示:

public class MealsAllocation
{
    public int mealId;
    public List<CrewSummary> crew;

    private MealsAllocation() { }
    public MealsAllocation(int MealId) {
        mealId = MealId;
        string connStr = ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString;
        SqlConnection conn = new SqlConnection(connStr);

        //first fill an ienumerable redemption object for the meal
        List<MealRedemption> mealRedemptions = new List<MealRedemption>();
        SqlCommand cmdRed = new SqlCommand("tegsGetMealsRedemption", conn);
        cmdRed.CommandType = CommandType.StoredProcedure;
        cmdRed.Parameters.Add(new SqlParameter("@mealId", MealId));
        conn.Open();
        SqlDataReader drRed = cmdRed.ExecuteReader();
        while (drRed.Read())
        {
            MealRedemption mr = new MealRedemption(Convert.ToInt32(drRed["crewId"]), Convert.ToDateTime(drRed["creation"]), Convert.ToInt32(drRed["redeemed"]));
            mealRedemptions.Add(mr);
        }
        conn.Close();

        //then fill the crew list
        crew = new List<CrewSummary>();
        SqlCommand cmdCrew = new SqlCommand("tegsGetMealsAllocation", conn);
        cmdCrew.CommandType = CommandType.StoredProcedure;
        cmdCrew.Parameters.Add(new SqlParameter("@mealId", MealId));
        conn.Open();
        SqlDataReader drCrew = cmdCrew.ExecuteReader();
        while (drCrew.Read())
        {
            int drCid = Convert.ToInt32(drCrew["id"]);
            List<MealRedemption> drMr = mealRedemptions.FindAll(red => red.crewId == drCid) ;
            CrewSummary cs = new CrewSummary(drCid, Convert.ToInt32(drCrew["allocation"]), drMr );
            crew.Add(cs);
        }
        conn.Close();

    }

那么现在我想添加一个新的重载,看起来有点像这样:

    public MealsAllocation(int MealId, int crewId)
    {
    }

本质上,这将与上述内容大致相同但略有不同。

避免“复制和粘贴继承”的好策略是什么?即重构上述内容的好方法,使其更容易承受重载?

4

5 回答 5

1

如何将您的逻辑移动到一个internal函数中,以便它只能在这个程序集中访问,以及这个类并使用可选参数......像这样:

public class MealsAllocation
{
    public int mealId;
    public List<CrewSummary> crew;

    private MealsAllocation() 
    {
    }

    public MealsAllocation(int MealId) 
    {
        DoWork(MealId);
    }

    public MealsAllocation(int MealId, int crewId)
    {
        DoWork(MealId, crewId);
    }

    internal void DoWork(int MealId, int crewId = -1)
    {
        // have your logic here based on your parameter list

        // valid crewId passed, then add new param for DB proc
        if (crewId > -1)
        {
            cmdCrew.Parameters.Add(new SqlParameter("@crewId", crewId));
        }
    }
}
于 2012-08-20T13:06:47.233 回答
1

您可以使用用户对象初始化程序

var mealRedemption = new
{ 
  MealId = yourvlue,
  Crew = crew
};

链接:http: //msdn.microsoft.com/en-us/library/bb384062.aspx

于 2012-08-20T13:06:48.617 回答
1

首先想到的是用两种不同的方法分割一大块代码,为每种方法提供一个专门的功能

public MealsAllocation(int MealId) 
{
    List<MealRedemption> mealRedemptions = LoadMealRedemptions(MealID);
    LoadCrewSummaryByMeal(mealRedemptions, MealID);
}

而另一个构造函数可能是

public MealsAllocation(int MealId, int crewId) 
{ 
    List<MealRedemption> mealRedemptions = LoadMealRedemptions(MealID);
    LoadCrewSummaryByCrew(mealRedemptions, MealID, crewID);
} 

在第一个构造函数中,您调用加载 MealRedemptions 列表的私有方法,获取其输出并传递给专门的方法,该方法仅使用 MealID 和从第一个方法获得的列表来加载 CrewSummary 列表。

在第二个构造函数中,您可以使用与第一个构造函数相同的方法,然后使用不同的方法来加载 CrewSummary。您的第二个构造函数的要求不明确,可能会更改第二种方法的设计(我的意思是,您如何使用 crewID 参数更改内部工作以构建 CrewSummary 列表?)

于 2012-08-20T13:07:20.113 回答
1

既然你想重载你的构造函数,你也可以尝试这样的方法:

public MealsAllocation(int MealId) : this (MealId, null)
{
}
public MealsAllocation(int MealId, int? crewId) 
{
  // Initialize your instance as needed
  if (crewId.HasValue)
  {
    // Do some more stuff
  }
}
于 2012-08-20T13:14:11.003 回答
1

尽管我不建议在构造函数中执行所有这些操作,但您可以简单地在末尾添加一个可选参数:

public class MealsAllocation  
{  
    public int MealId { get; set; }
    public int CrewId { get; set; }

    public List<CrewSummary> Crew { get; set; };

    public MealsAllocation(int mealId, int crewId = 0)  
    {  
        this.MealId = mealId;
        this.CrewId = crewId;

        if(this.CrewId = 0) // etc...
} 

旁注:您需要在,和对象using周围添加语句,否则您可能会遇到连接和/或内存泄漏。就个人而言,我会创建一个数据访问层并将所有与数据相关的方法放在那里,以使它们在整个业务层中可重用。SqlConnectionSqlCommandSqlDataReader

另外,我认为这可能是该Lazy<T>对象的一个​​很好的候选者:http: //msdn.microsoft.com/en-us/library/dd642331.aspx

于 2012-08-20T13:14:39.387 回答