2017-04-20 92 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());