C#在switch语句中定义子类

pis*_*sk1 1 c# entity-framework asp.net-mvc-5

我正在尝试基于输入创建子类的新实例.为此,我正在使用switch语句.

[HttpPost]
public ActionResult Register(RegisterViewModel model)
{
    var user = new User();

    switch (model.UserType)
    {
        case UserType.Normal:
            user = (NormalUser) user;
            // NormalUser properties cannot be defined here
            break;
        case UserType.Vip:
            user = (VipUser) user;
            // VipUser properties cannot be defined here
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

寻找解决这个问题的最佳解决方案.

Him*_*ere 5

在使用时,new User()您正在创建此类的新实例,该实例不了解其任何子类.因此,铸造任何一个都失败了.

问题是程序无法知道在执行强制转换时如何NormalUser设置在基类中定义但不在基类中的成员.所以,想象你的基类成员拥有Name和地址,and yourNormalUser has an年龄-property in addition to those two ones. What would you expect would the年龄be when casting your existing用户toNormalUser . Your program can´t know how to setAge`.

您必须为此创建一个复制构造函数,或者在切换之前不要实例化变量:

User user;

switch (model.UserType)
{
    case UserType.Normal:
        user = new NormalUser();
        break;
    case UserType.Vip:
        user = new VipUser()
        break;
}
Run Code Online (Sandbox Code Playgroud)

这遵循工厂模式,因此此方法的用户可以使用它来创建给定类型的实例,而不依赖于该类型,从而减少客户端代码与工厂中创建的实际类型的耦合.

default如果没有条件通过,你还需要一些-switch让编译器知道该怎么做 - 即使在你的场景中这是不可能的.例如,您可能会在这种情况下抛出异常.

复制构造函数的选项来自:

class NormalUser
{
    public NormalUser(User user, int age)
    {
        this.Name = user.name;
        this.Adress = user.Adress;
        // further properties defined in the base-class

       this.Age = age
       // further properties defined in NormalUser
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,这是对属性的大量复制.特别是第一个选项更适合你的sneario.