我正在尝试使用C#中的三个类。这些类非常相似,但有一些细微的变化。因为每个类都不同并存储在一个单独的DB表中,所以我需要函数来返回每个类类型,但由于它们非常相似,所以它们几乎可以在我的控制器中用相同的函数编写。
我宁愿不在我的控制器中编写完全相同的函数集,除了输入/输出类之外没有区别,但我不能为我的生活弄清楚如何。
我尝试过多态,但我会说实话,因为我无法访问父类中的子类属性而且它只是一团糟,所以我将这些类分离出来是非常混乱的。
如何正确使用这三个截然不同的类?
这就是我目前所拥有的,但不起作用,因为task
无法在switch
语句中声明。 (这将理想地解决我的问题)。我也不能在switch
之外声明一个泛型变量,并在switch
内给它一个类型,因为C#不允许这样做。
var type = _projectService.GetTaskTypeById(id);
/* object task; doesn't work. I can declare it inside the switch statement
but it doesn't "become" the new type (the last line throws an error:
"object does not contain a definition for ToModel()")
*/
switch (type)
{
case "MS":
var task = _projectService.GetMSTaskById(id);
break;
case "TL":
var task = _projectService.GetTLTaskById(id);
break;
case "ET":
var task = _projectService.GetETTaskById(id);
break;
default:
// throw error
}
task.ToModel();
答案 0 :(得分:3)
您能够希望的最好的方法是使用继承或接口。从具有所有相似功能的基类开始,然后让三个不同类中的每一个继承此类。最后,而不是使用" var"要定义对象任务,请使用在switch语句之前定义的基类。
答案 1 :(得分:1)
正确的答案是声明一个共同的基类或接口,但你说"我尝试过多态,但是"。我不知道你尝试了什么(或如何),但是假设,
ToModel()
方法你可以做到
var type = _projectService.GetTaskTypeById(id);
dynamic task;
switch (type)
{
case "MS":
task = _projectService.GetMSTaskById(id);
break;
case "TL":
task = _projectService.GetTLTaskById(id);
break;
case "ET":
task = _projectService.GetETTaskById(id);
break;
default:
throw new NotSupportedException("Unsupported Task Type: " + type);
}
task.ToModel();
答案 2 :(得分:1)
就我个人而言,我做的事情......
public interface IProjectTask
{
Task GetTaskById(int id);
}
public enum ProjectTaskTypes
{
MS = 1,
TL = 2,
ET = 3
}
public class ProjectTaskFactory
{
public static IProjectTask GetInstance(ProjectTaskTypes projectTaskType,
int projectTaskId)
{
IProjectTask task;
switch(projectTaskType)
{
case ProjectTaskTypes.MS:
task = new MSProjectTask(projectTaskId);
break;
case ProjectTaskTypes.TL:
task = new TLProjectTask(projectTaskId);
break;
case ProjectTaskTypes.ET:
task = new ETProjectTask(projectTaskId);
break;
default:
// throw error
}
return task;
}
}
//usage
var projectTask = ProjectTaskFactory.GetInstance(type);
projectTask.ToModel()
正如旁注 - 为项目类型创建一个枚举我感觉更好,代码中没有神奇的字符串,并且更易于阅读。
将它们分开不仅是单一责任模式的一部分,而且还意味着编写单元测试可能更容易。