基于条件的继承构造函数选择

时间:2018-05-30 23:16:31

标签: c#

我有一组继承的类。根据初始化变量类型,我需要调用相应的构造函数。 我想避免在这里使用switch分支,以防万一武器类型会越来越多。也许有通用的方法或一些模式来实现这一目标? 武器初始化:

switch (_weaponsData.WeaponType) 
{
    case WeaponType.ProjectileWeapon:
    weapon = new ProjectileWeapon(_weaponsData);
    break;

    case WeaponType.Laser:
    weapon = new LaserWeapon(_weaponsData);
    break;

    case WeaponType.snowBall:
    weapon = new SnowballWeapon(_weaponsData);
    break;
}

自定义武器的构造者:

public class ProjectileWeapon : BasicWeapon
{
    public ProjectileWeapon(WeaponData weaponData) : base(weaponData) { }
}

public class LaserWeapon : BasicWeapon
{
    public LaserWeapon(WeaponData weaponData) : base(weaponData) { }
}

public class SnowballWeapon : BasicWeapon
{
    public SnowballWeapon(WeaponData weaponData) : base(weaponData) { }
}

2 个答案:

答案 0 :(得分:6)

这种事情是不可避免的,但是如果你真的想要避免使用case switch结构,你可以使用代理词典,其中键是类型,值是Func<BasicWeapon>

var map = new Dictionary<WeaponType,Func<WeaponData,BasicWeapon>>
{
    { WeaponType.ProjectileWeapon, d => new ProjectileWeapon(d) },
    { WeaponType.LaserWeapon,      d => new LaserWeapon(d) },
    { WeaponType.SnowballWeapon,   d => new SnowballWeapon(d) },
};

然后要创建一个新的武器对象,只需调用

weapon = map[_weaponsData.WeaponType](_weaponsData);

答案 1 :(得分:0)

在基类中定义静态方法以处理新实例的创建:

public class BasicWeapon
{
    public static BasicWeapon CreateNew(WeaponData _weaponsData)
    {
        // As @Gusman said in comments, if you store Type of classes in 
        // _weaponsData, then you can use :
        // return Activator.CreateInstance(_weaponsData.Type, _weaponsData);
        // Or:
        switch (_weaponsData.WeaponType)
        {
            case WeaponType.ProjectileWeapon:
                return new ProjectileWeapon(_weaponsData);
            case WeaponType.Laser:
                return new LaserWeapon(_weaponsData);
            case WeaponType.snowBall:
                return new SnowballWeapon(_weaponsData);
            default: return null;
        }
    }
}

随时随地都可以使用:

var weapon = BasicWeapon.CreateNew(_weaponsData);