按枚举

时间:2017-04-20 16:46:36

标签: c# class enums

嗨,我有一个抽象类Item。食物,武器等类继承于此类。有关此项的所有信息都存储在数据库中,C#Code的工作与确切的类匹配,并与Enum匹配,Enum也作为整数存储在数据库列中。我的问题是这个愚蠢的代码,无论我在哪里使用食物,武器等类的方法

if ((ItemType)userItem.ItemType == ItemType.Food)
{
    Food food = new Food(userItem);
    food.UseItem(sender);
}
else if ((ItemType)userItem.ItemType == ItemType.Weapon)
{
    Weapon weapon = new Weapon(userItem);
    weapon.UseItem(sender);
}

在Food,Weapon等构造函数的参数中,类是数据库中的对象,让它知道对象的字段。

在没有此代码的情况下,某种东西可以帮助我匹配这些类型吗?当我看着它时,它真的很烦我。

2 个答案:

答案 0 :(得分:4)

您可以使用工厂或创建方法创建特定类型的项目:

public Item CreateItem(UserItem userItem)
{
    var itemType = (ItemType)userItem.ItemType;
    switch(itemType)
    {
        case ItemType.Food: return new Food(userItem);
        case ItemType.Weapon: return new Weapon(userItem);
        // etc
        default:
            throw new NotSupportedException($"Item type {itemType} is not supported");
    }
}

然后使用此方法创建项目并使用它们。例如。您当前的代码如下所示:

var item = CreateItem(userItem);
item.UseItem(sender); // you don't care about specific type of item

注意:EF可以使用 discriminator 列自动创建适当类型的实体。

答案 1 :(得分:2)

只需注册一次构建​​动作:

var builder = new ItemBuilder()
    .RegisterBuilder(ItemType.Food, () => new Food())
    .RegisterBuilder(ItemType.Weapon, () => new Weapon());

然后像这样使用它:

   var item1 = builder.Build(ItemType.Food);
   item1.UseItem(sender)

这里有一个构建器代码:

public class ItemBuilder
{
    public ItemBase Build(ItemType itemType)
    {
        Func<ItemBase> buildAction;

        if (itemBuilders.TryGetValue(itemType, out buildAction))
        {
            return buildAction();
        }

        return null;
    }

    public ItemBuilder RegisterBuilder(ItemType itemType, Func<ItemBase>  buildAction)
    {
        itemBuilders.Add(itemType, buildAction);
        return this;
    }

    private Dictionary<ItemType, Func<ItemBase>> itemBuilders = new Dictionary<ItemType, Func<ItemBase>> ();
}

另一种选择使用像DI或somth这样的DI容器:

UnityContainer.RegisterType<IItemBase, Food>("ItemType.Food");
UnityContainer.RegisterType<IItemBase, Weapon>("ItemType.Weapon");

并解决

 var item1 = UnityContainer.Resolve<IItemBase>(ItemType.Food.ToString());