我有三个具有相同命名属性的类。假设类为Sword
,Bow
和Hammer
,而属性为Damage
和Range
。如何通过构造函数实例化Weapon<T>
的类,并在其中传递int
以选择此类的Type?
我不确定这是否是我想要做的正确方法。
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; }
}
答案 0 :(得分:6)
您所描述的称为工厂模式。您有一些工厂可以实例化其他对象,在这种情况下,取决于整数:
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; }
}
最后,所有类都应实现该接口。现在,您可以使用以下代码轻松创建实例:
var hammer = WeaponFactory.CreateWeapon(WeaponType.Hammer);
答案 1 :(得分:5)
除了您提出的其他解决方案之外,我还将简化此操作。
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;
}
这里实际上不需要多态-您要做的就是在运行时分配不同的只读值。如果以后想要每种武器的行为不同,则可以使用策略模式来实现。
然后我只需要使用工厂来实例化不同的武器。
这些工厂的外观取决于调用方式,但实际上,您的工厂方法可能如下所示:
public Weapon GetWeapon(string weaponType)
{
var weaponProperties = propertiesFor(weaponType);
return new Weapon(weaponProperties.Range, weaponProperties.Damage);
}
propertiesFor
在字典,文件等中查找给定武器类型的适当值。
除非您确实需要在运行时提供武器的不同实现,否则我将避免使用IWeapon
接口。直到您需要它之前,都不要写它。声明接口只是为了在测试中进行模拟(正如其他人所建议的那样)通常会向我表明您的测试边界已关闭,或者您有一些依赖关系可以更好地隔离(但这是更广泛的讨论)。
答案 2 :(得分:4)
public interface IWeapon
{
int Damage { get; }
int Range { get; }
}
public class Weapon : IWeapon
{
protected int _damage, _range;
public int Damage
{
get { return _damage; }
}
public int Range
{
get { return _range; }
}
}
public class Sword : Weapon
{
public Sword()
{
_damage = 10;
_range = 12;
}
}
public class Bow : Weapon
{
public Bow()
{
_damage = 8;
_range = 28;
}
}
public class Hammer : Weapon
{
public Hammer()
{
_damage = 15;
_range = 8;
}
}
答案 3 :(得分:2)
从基类继承
public class Weapon
{
public int Damage { get; set; }
public int Range { get; set; }
}
public class Sword : Weapon
{
}
public class Bow : Weapon
{
}
public class Hammer : Weapon
{
}
并通过这种方式实例化
Weapon item = new Sword() { Damage = 10, Range = 20 };
答案 4 :(得分:1)
您可以从为父武器类创建界面开始。然后用子类扩展武器类,以制作剑,锤子等。然后,您可以为每个子类添加自定义属性,并且仍将它们用作武器,因为它们共享相同的接口/父类并且都具有攻击方法。
public interface IWeapon
{
int Damage { get; }
int Range { get; }
void Attack();
}
public class Weapon : IWeapon
{
public int Damage { get; private set; }
public int Range { get; private set; }
public Weapon(int damage, int range)
{
Damage = damage;
Range = range;
}
public virtual void Attack()
{
Console.WriteLine("Weapon: Attack");
}
}
public class Sword : Weapon
{
//some sword properties here...
public Sword(int damage, int range) : base(damage, range)
{
}
public override void Attack()
{
Console.WriteLine("Weapon Sword: Attack");
}
}
public class Bow : Weapon
{
//some bow properties here...
public Bow(int damage, int range) : base(damage, range)
{
}
public override void Attack()
{
Console.WriteLine("Weapon Bow: Attack");
}
}
public class Hammer : Weapon
{
//some hammer properties here...
public Hammer(int damage, int range) : base(damage, range)
{
}
public override void Attack()
{
Console.WriteLine("Weapon Hammer: Attack");
}
}
class Program
{
public static void Main(string[] args)
{
IWeapon hammerWeapon = new Hammer(15, 10);
hammerWeapon.Attack();
}
}