2017-04-20 89 views
3

嗨,我有一个抽象类Item。食物,武器等类继承这个类。有关这些项目的所有信息都存储在数据库中,C#代码的工作与确切的类匹配,并通过Enum进行匹配,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); 
} 

在食品的构造函数的参数食品的方法,武器等类是从数据库中的对象,让了解它的领域对象。

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

+0

尝试看看,可能会有帮助 http://stackoverflow.com/questions/43278791/polymorphic-object-creation-without-if-condition/43279301# 43279301。主要想法是通过结构创建对象,然后调用项目的polimorfic方法 – gabba

回答

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可以使用鉴别列自动创建相应类型的实体。

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像统一或索引的容器:

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

和解决

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