我有三个类具有相同的名称属性.让我们说这些类是Sword,Bow和Hammer- 属性是Damage和Range.我如何Weapon<T>用构造函数实例化一个类,我传递一个类int来选择这个类的类型?
我不确定这是否是做我想做的正确方法.
public class Weapon<T>
{
}
public class Sword
{
public int Damage { get => 10; }
public int Range { get => 12; }
}
public class Bow
{
public int Damage { get => 8; }
public int Range { get => 28; }
}
public class Hammer
{
public int Damage { get => 15; }
public int Range { get => 8; }
}
Run Code Online (Sandbox Code Playgroud)
你所描述的被称为工厂模式.您有一些能够实例化其他对象的工厂,在您的情况下取决于整数:
class WeaponFactory
{
public static IWeapon CreateWeapon(WeaponType type)
{
switch type:
case WeaponType.Sword: return new Sword();
case WeaponType.Hammer: return new Hammer();
case WeaponType.Bow: return new Bow();
default: throw new ArgumentException("Unknown weaponType");
}
}
enum WeaponType { Sword, Hammer, Bow }
interface IWeapon
{
int Damage { get; }
int Range { get; }
}
Run Code Online (Sandbox Code Playgroud)
最后,所有类都应该实现该接口.现在,您可以使用以下代码轻松创建实例:
var hammer = WeaponFactory.CreateWeapon(WeaponType.Hammer);
Run Code Online (Sandbox Code Playgroud)
我会将此简化为超出您所拥有的范围,并超出所提出的其他解决方案.
public class Weapon
{
private int _range;
private int _damage;
public Weapon(int range, int damage)
{
_range = range;
_damage = damage;
}
public int Range => _range;
public int Damage => _damage;
}
Run Code Online (Sandbox Code Playgroud)
这里没有真正需要多态性 - 你想要做的就是在运行时分配不同的readonly值.如果您以后想要每种武器的不同行为,您可以使用策略模式实现这一点.
然后我会用工厂来实例化不同的武器.
这些工厂的样子取决于他们需要如何调用,但实际上你的工厂方法看起来像这样:
public Weapon GetWeapon(string weaponType)
{
var weaponProperties = propertiesFor(weaponType);
return new Weapon(weaponProperties.Range, weaponProperties.Damage);
}
Run Code Online (Sandbox Code Playgroud)
在propertiesFor字典,文件等中查找给定武器类型的适当值.
IWeapon除非你真的需要在运行时提供不同的武器实现,否则我会避开接口.不要写它直到你需要它.声明一个接口只是为了在测试中进行模拟(正如其他人所建议的那样)通常会向我表明你的测试边界已经关闭,或者你有一些依赖关系要更好地隔离(但这是一个更广泛的对话).