簡體   English   中英

通用類 <T> 用構造函數選擇類型

[英]Generic class<T> with constructor to choose the type

我有三個具有相同命名屬性的類。 假設類是SwordBowHammer ,而屬性是DamageRange 我該如何用構造函數實例化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; }
}

您所描述的稱為工廠模式。 您有一些工廠可以實例化其他對象,在這種情況下,取決於整數:

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

除了您提出的解決方案之外,我還將簡化此過程。

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接口。 直到您需要它之前,都不要寫它。 聲明一個接口只是為了在測試中進行模擬(正如其他人所建議的那樣)通常會向我表明您的測試邊界已關閉或您有一些依賴關系可以更好地隔離(但這是更廣泛的討論)。

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;
    }
}

從基類繼承

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 };

您可以從為父武器類創建接口開始。 然后用子類擴展武器類,以制作劍,錘子等。然后,您可以為每個子類添加自定義屬性,並且仍將它們用作武器,因為它們共享相同的接口/父類並且都具有攻擊方法。 。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM