使用多态性获取相同类型的实例



我有下一个场景:有一个类负责管理应用程序的所有货币。所有货币都扩展了Currency,所以它可以像它一样工作。Currency是抽象的,所以它不能实例化。在应用程序的某些部分,我使用软、硬或事件货币作为成本货币,例如,玩家按下某些菜单上的某些购买按钮。此操作触发购买,购买具有货币作为参考,在本例中可以是costSoftCurrency。这个想法是,如果玩家货币收到一个货币,玩家货币会评估他的货币,并返回相同类型的相关货币,然后你可以安全地减去成本。

我的问题是…如果没有这些可怕的假设,我怎么能得到同样的逻辑?我读过关于双重派遣的文章,但我不知道它是否可以在这里应用。

有人知道这是否可以实现吗?

public class PlayerCurrencies
{
public SoftCurrency softCurrency = new SoftCurrency();
public HardCurrency hardCurrency = new HardCurrency();
public EventCurrency eventCurrency = new EventCurrency();
public Currency GetCurrencyFromType(Currency currency)
{
if (currency is SoftCurrency)
{
return this.softCurrency;
}
if (currency is HardCurrency)
{
return this.hardCurrency;
}
if (currency is EventCurrency)
{
return this.eventCurrency;
}
return null;
}
}
public abstract class Currency
{
public float Value
{
get;
set;
}
public void Add(Currency currency)
{
this.Value += currency.Value;
}
public void Substract(Currency currency)
{
this.Value -= currency.Value;
}
}
public class EventCurrency : Currency
{
}
public class HardCurrency : Currency
{
}
public class SoftCurrency : Currency
{
}
internal class Program
{
private static void Main(string[] args)
{
PlayerCurrencies playerCurrencies = new PlayerCurrencies();
Currency costSoftCurrency = new SoftCurrency();
Currency costHardCurrency = new HardCurrency();
playerCurrencies.GetCurrencyFromType(costSoftCurrency).Substract(costSoftCurrency); // there i get a SoftCurrency from Player Currencies 
playerCurrencies.GetCurrencyFromType(costHardCurrency).Substract(costHardCurrency); // there i get a HardCurrency from Player Currencies 
}
}

我会为此使用工厂方法设计模式,因为它专门用于使用子类来确定应该创建哪些类的时候。这基本上就是你在这里所做的。我最初的回答提到了反思,因为我在链接到的网站上看到了映射配置,觉得这很酷,但经过昨晚的思考,它也有很多开销。通过使用Dictionary绕过if块或switch语句将不会那么复杂,也会更快。

这是我想添加/更改的关于您的代码:

//The Factory class that creates the different types of currency based
//on a name parameter
static class CurrencyFactory
{
private static readonly Dictionary<string, Currency> _currencyDictionary =
new Dictionary<string, Currency>
{
{ "HardCurrency", new HardCurrency() },
{ "SoftCurrency", new SoftCurrency() },
{ "EventCurrency", new EventCurrency() }
};
public static Currency Create(string currencyTypeName)
{
return _currencyDictionary[currencyTypeName];
}
}
internal class Program
{
private static void Main(string[] args)
{
//This class will no longer be needed as it is redundant
PlayerCurrencies playerCurrencies = new PlayerCurrencies();
var costSoftCurrency = CurrencyFactory.Create("softCurrency");
var costHardCurrency = CurrencyFactory.Create("hardCurrency");
//I wasn't sure of your goals here so I kept it as is,
//but as I said above, playerCurrencies won't be needed.
playerCurrencies.GetCurrencyFromType(costSoftCurrency)
.Substract(costSoftCurrency); // there i get a SoftCurrency from Player Currencies 
playerCurrencies.GetCurrencyFromType(costHardCurrency)
.Substract(costHardCurrency); // there i get a HardCurrency from Player Currencies 
}
}

你可以在这里找到一个更全面的例子和对模式的解释:https://dev.to/gary_woodfine/how-to-use-factory-method-design-pattern-in-c-3ia3

您可以通过模式匹配来实现这一点:

public class PlayerCurrencies
{
public SoftCurrency Soft = new SoftCurrency();
public HardCurrency Hard = new SoftCurrency();
public EventCurrency Event = new EventCurrency();
public Currency GetCurrencyFromType(Currency currency)
{
switch (currency)
{
case EventCurrency: return Event;
case HardCurrency: return Hard;
case SoftCurrency: return Soft;
}
return null;
}
}

我将字段的名称更改为HardSoftEvent,以便更容易地将它们与具有相同名称的类型区分开来。

在这个特定的示例中,传入currency参数并仅将其用于其类型似乎很奇怪。也许还有另一种方法可以解决你的具体问题。但至于如何在没有多个if语句的情况下做到这一点,这就是你可以做到的

您最常看到的是用声明的变量来演示这一点,如下所示:

switch (currency)
{
case EventCurrency ec : return Event;
case HardCurrency hc: return Hard;
case SoftCurrency sc: return Soft;
}
return null;

例如,如果currency的类型是EventCurrency,那么在case的范围内,ec将是转换为EventCurrencycurrency参数。但是由于在这个例子中没有使用值,所以不需要变量。

最新更新