我想从我的代码中删除嵌套的do-while循环。 我使用这些嵌套的do-while来重新输入值,如果它无效,我正在验证Employee类中的值。 我是c#的新手,所以请帮我减少这段代码。
FirstName,LastName是属性。
我将嵌套的do-while复制到方法中,并将employeeDetails.FirstName和employeeDetails.LastName作为方法的参数发送,但它不起作用,因为FirstName和LastName是该类的属性。
这是我的入门级。
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Employee_Details
{
class EntryClass
{
static void Main(string[] args)
{
string strChoice;
List<Employee> employeeList = new List<Employee>();
do
{
Employee employeeDetails = new Employee();
bool exception=false;
do
{
Console.WriteLine("Enter first name");
try
{
employeeDetails.FirstName = Console.ReadLine();
exception = false;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
exception = true;
}
} while (exception);
exception = false;
do
{
Console.WriteLine("enter last name");
try
{
employeeDetails.LastName = Console.ReadLine();
exception = false;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
exception = true;
}
} while (exception);
exception = false;
do
{
Console.WriteLine("enter date of birth in dd/MM/yyyy ");
try
{
employeeDetails.SetDOB(Console.ReadLine());
exception = false;
}
catch(Exception e)
{
Console.WriteLine(e.Message);
exception = true;
}
} while (exception);
employeeList.Add(employeeDetails);
Console.WriteLine("Do You want to continue?");
strChoice = Console.ReadLine().ToLower();
} while (strChoice == "yes");
var query = from employeeDetails in employeeList
select new
{
firstName = employeeDetails.FirstName,
lastName = employeeDetails.LastName,
dob = employeeDetails.DateOfBirth.ToString("d/M/yyyy", System.Globalization.CultureInfo.InstalledUICulture),
age=employeeDetails.GetAge()
};
foreach (var employee in query)
{
Console.WriteLine($"{employee.firstName},{employee.lastName},{employee.dob},{employee.age}");
}
}
}
}
我的入门课程看起来像这样。
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Employee_Details
{
class Employee
{
private string first_name;
private string last_name;
private DateTime date_of_birth;
public DateTime DateOfBirth => date_of_birth;
public void SetDOB(string dob)
{
if (!DateTime.TryParseExact(dob, "d/M/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime returnDate))
{
throw new Exception("Invalid Date");
}
else if (GetAge() <= 0)
{
throw new Exception("Birth Year shoud not be greater then current year");
}
date_of_birth= returnDate;
}
public string LastName
{
set
{
last_name = CheckString(value);
}
get
{
return last_name;
}
}
public string FirstName
{
set
{
first_name = CheckString(value);
}
get
{
return first_name;
}
}
private string CheckString(string value)
{
string returnString = "";
var regex = new Regex(@"(?i)^[a-z.,\s]+$");
bool res = regex.IsMatch(value);
if (res)
{
returnString = value;
}
else
{
throw new Exception("Invalid String");
}
return returnString;
}
public int GetAge()
{
DateTime now = DateTime.Today;
int age = now.Year - date_of_birth.Year;
return age;
}
}
}
当我们提供任何无效数据时,FirstName,LastName和DateOfBirth将抛出异常。
答案 0 :(得分:3)
使用DateTime.TryParse
代替捕获例外。你可以改进一些事情,比如说。为什么在从不抛出异常的属性上使用异常循环,比如从控制台读取FirstName
和LastName
?
使其更具可读性的一种方法是定义Func
代理:
Func<bool> askContinue = () =>
{
Console.WriteLine("Do You want to continue?");
return Console.ReadLine().Trim().Equals("yes", StringComparison.InvariantCultureIgnoreCase);
};
Func<string> askFirstName = () =>
{
Console.WriteLine("Enter first name");
return Console.ReadLine().Trim();
};
Func<string> askLastName = () =>
{
Console.WriteLine("Enter last name");
return Console.ReadLine().Trim();
};
Func<DateTime?> askDateOfBirth = () =>
{
Console.WriteLine("Enter date of birth(dd/MM/yyyy)");
string dobStr = Console.ReadLine().Trim();
DateTime dob;
if (DateTime.TryParse(dobStr, out dob))
return dob;
return null;
};
现在循环本身被简化为必要且可读:
List<Employee> employeeList = new List<Employee>();
bool addEmployee = true;
while (addEmployee)
{
var emp = new Employee
{
FirstName = askFirstName(),
LastName = askLastName()
};
DateTime? dob = askDateOfBirth();
while (!dob.HasValue)
dob = askDateOfBirth();
emp.DateOfBirth = dob.Value;
employeeList.Add(emp);
addEmployee = askContinue();
}
答案 1 :(得分:0)
您可以创建一个返回名称的方法:
private static string GetName(string question)
{
string name = null;
do
{
Console.WriteLine(question);
try
{
name = Console.ReadLine();
}
catch (Exception e)
{
name = null;
Console.WriteLine(e.Message);
}
} while (string.IsNullOrEmpty(name));
return name;
}
然后在你的程序中你可以设置你的行为:
do {
var employeeDetails = new Employee
{
FirstName = GetName("Enter firstname and press enter."),
LastName = GetName("Enter firstname and press enter."),
};
employeeList.Add(employeeDetails);
Console.WriteLine("Do You want to continue?");
strChoice = Console.ReadLine().ToLower();
} while (strChoice == "yes");
现在添加DOBgetter,你去了,你已经成功地减少了嵌套。