嗨,我有一个抽象类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等构造函数的参数中,类是数据库中的对象,让它知道对象的字段。
在没有此代码的情况下,某种东西可以帮助我匹配这些类型吗?当我看着它时,它真的很烦我。
答案 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());