使用多个班级

时间:2015-08-19 20:34:36

标签: c#

我正在尝试使用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();

3 个答案:

答案 0 :(得分:3)

您能够希望的最好的方法是使用继承或接口。从具有所有相似功能的基类开始,然后让三个不同类中的每一个继承此类。最后,而不是使用" var"要定义对象任务,请使用在switch语句之前定义的基类。

答案 1 :(得分:1)

正确的答案是声明一个共同的基类或接口,但你说"我尝试过多态,但是"。我不知道你尝试了什么(或如何),但是假设,

  1. 您确定所有课程都有ToModel()方法
  2. 为类声明公共接口或基类是不切实际的
  3. 您使用的是.NET 4.0或更高版本
  4. 你可以做到

    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()

正如旁注 - 为项目类型创建一个枚举我感觉更好,代码中没有神奇的字符串,并且更易于阅读。

将它们分开不仅是单一责任模式的一部分,而且还意味着编写单元测试可能更容易。