[英]Best Implementation to avoid if/else
I am doing a program for vacation in a company and the time that is allowed to be in a specific holiday.我正在公司做一个假期计划,以及允许在特定假期中的时间。
I used an Abstract class with an abstract method :我使用了一个带有抽象方法的抽象类:
public abstract class Abstract : TimeLength
{
public AbstractTest(string employeeCode, string employee, string typeOfHoliday, DateTime startDate, DateTime endDate) : base(startDate, endDate, "")
{
TypeOfHoliday = typeOfHoliday;
Employee = employee;
EmployeeCode = employeeCode;
}
public string EmployeeCode { get; set; }
public string Employee { get; set; }
public string TypeOfHoliday { get; set; }
public abstract bool HolidayValidation(string typeOfHoliday);
}
And I used multiple class that inherent from this abstract class like this two :我使用了这个抽象类固有的多个类,比如这两个:
class MarriageVacation : Abstract
{
public MarriageVacation(string employeeCode, string employee, string typeOfHoliday, DateTime startDate, DateTime endDate) : base(employeeCode, employee, typeOfHoliday, startDate, endDate)
{
}
public override bool HolidayValidation(string typeOfHoliday)
{
if (Days() > (int)Holiday.MarriageVacation)
{
MessageBox.Show("Marriage Vacation Can only be 5 Days");
return false;
}
else
return true;
}
}
class Bereavement : Abstract
{
public Bereavement(string employeeCode, string employee, string typeOfHoliday, DateTime startDate, DateTime endDate) : base(employeeCode, employee, typeOfHoliday, startDate, endDate)
{
}
public override bool HolidayValidation(string typeOfHoliday)
{
if (Days() > (int)Holiday.Bereavement)
{
MessageBox.Show("Bereavement Can only be 5 Days");
return false;
}
else
return true;
}
}
I use Enum
for holidays and in the main
I want to register this based on the users choice like this :我将
Enum
用于假期, main
我想根据用户的选择进行注册,如下所示:
List<Abstract> holiday = new List<Abstract>();
if(CmbTypeHolidays.Text == Holiday.Bereavement.ToString())
{
var holid = new Bereavement(CmbEmpHolidays.Text.Split('-')[0], CmbEmpHolidays.Text.Split('-')[1], CmbTypeHolidays.Text, Convert.ToDateTime(StartDateHolidays.Value), Convert.ToDateTime(EndDateHolidays.Value));
if (holid.HolidayValidation(CmbTypeHolidays.Text))
{
holiday.Add(holid);
var bindingList = new BindingList<Abstract>(holiday);
dataGridHolidays.DataSource = bindingList;
controlPanelHolidays.Visible = false;
}
}
else if (CmbTypeHolidays.Text == Holiday.MarriageVacation.ToString())
{
var holid = new MarriageVacation(CmbEmpHolidays.Text.Split('-')[0], CmbEmpHolidays.Text.Split('-')[1], CmbTypeHolidays.Text, Convert.ToDateTime(StartDateHolidays.Value), Convert.ToDateTime(EndDateHolidays.Value));
if (holid.HolidayValidation(CmbTypeHolidays.Text))
{
holiday.Add(holid);
var bindingList = new BindingList<Abstract>(holiday);
dataGridHolidays.DataSource = bindingList;
controlPanelHolidays.Visible = false;
}
}
I wanted to know a better way to implement this solution or just to change the code that inserts data to the abstract List我想知道实现此解决方案的更好方法,或者只是更改将数据插入抽象列表的代码
You will need to set up a factory that maps holiday type name to the class implementing it:您需要设置一个工厂,将假日类型名称映射到实现它的类:
private class HolidayConstructorArgs {
public string EmployeeCode {get;set;}
public string Employee {get;set;}
public string TypeOfHoliday {get;set;}
public DateTime From {get;set;}
public DateTime To {get;set;}
}
private static readonly IDictionary<string,Func<HolidayConstructorArgs,AbstractHoliday>> HolidayByTypeCode =
new Dictionary<string,Func<HolidayConstructorArgs,AbstractHoliday>> {
[$"{Holiday.Bereavement}"] = a => new Bereavement(a.EmployeeCode, a.Employee, a.TypeOfHoliday, a.From, a.To)
, [$"{Holiday.MarriageVacation}"] = a => new MarriageVacation(a.EmployeeCode, a.Employee, a.TypeOfHoliday, a.From, a.To)
};
Now you can get the factory from the dictionary, and use it to instantiate the object:现在您可以从字典中获取工厂,并使用它来实例化对象:
if (HolidayByTypeCode.TryGetValue(CmbTypeHolidays.Text, out var factory)) {
// This is where the "magic" happens:
// Func<> will invoke the appropriate constructor without a conditional
var holid = factory(
new HolidayConstructorArgs {
EmployeeCode = CmbEmpHolidays.Text.Split('-')[0]
, Employee = CmbEmpHolidays.Text.Split('-')[1]
, TypeOfHoliday = CmbTypeHolidays.Text
, From = Convert.ToDateTime(StartDateHolidays.Value)
, To = Convert.ToDateTime(EndDateHolidays.Value)
}
);
// ... The rest of your code remains the same
}
You have the same(almost) implementation for HolidayValidation
and you dont use typeOfHoliday
.您对
HolidayValidation
具有相同(几乎)的实现,并且不使用typeOfHoliday
。
From what you have posted you might as well add the Holiday enum as parameter and property to base class( Abstract
) and not have any inheritance at all.根据您发布的内容,您不妨将 Holiday 枚举作为参数和属性添加到基类(
Abstract
),而根本没有任何继承。 Implement the HolidayValidation
in the base class and use the Holiday property to compare to Days
在基类中实现
HolidayValidation
并使用 Holiday 属性与Days
进行比较
I made this changes based on the answers on this questions this is the Main class (Abstract) :我根据这个问题的答案做了这个改变,这是主类(抽象):
public class AbstractTest : TimeLength
{
public AbstractTest(string employeeCode, string employee, Holiday typeOfHoliday, DateTime startDate, DateTime endDate) : base(startDate, endDate, "")
{
TypeOfHoliday = typeOfHoliday;
Employee = employee;
EmployeeCode = employeeCode;
}
public string EmployeeCode { get; set; }
public string Employee { get; set; }
public Holiday TypeOfHoliday { get; set; }
public bool HolidayValidation(Holiday typeOfHoliday)
{
return Days() > (int)typeOfHoliday;
}
}
And in the Main i changed into this :在Main我变成了这个:
Holiday MyStatus = (Holiday)Enum.Parse(typeof(Holiday), CmbTypeHolidays.Text, true);
var holid = new AbstractTest(CmbEmpHolidays.Text.Split('-')[0], CmbEmpHolidays.Text.Split('-')[1], MyStatus, Convert.ToDateTime(StartDateHolidays.Value), Convert.ToDateTime(EndDateHolidays.Value));
if (!holid.HolidayValidation(MyStatus))
{
holiday.Add(holid);
var bindingList = new BindingList<AbstractTest>(holiday);
dataGridHolidays.DataSource = bindingList;
controlPanelHolidays.Visible = false;
}
else
{
MessageBox.Show($"{holid.TypeOfHoliday} Cant be more than {(int)MyStatus} Days");
}
For the typeOfHoliday i used Holiday type so it is easier to work with and the choice that the user makes i convert it to Enum Holiday对于typeOfHoliday,我使用了Holiday类型,因此使用起来更容易,并且用户做出的选择我将其转换为Enum Holiday
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.