[英]Faster way to compare enums?
我正在尋找比較枚舉的更好方法。 當前,我有一個帶有3個不同可能值的枚舉:
public enum Elements { fire, water, earth };
但是,有一個函數示例,其中兩個元素碰撞時會發生某些事情:
Public Void ElementCollisionExample(Elements element1, Elements element2){
if (element1 == Elements.fire){
if (element2 == Elements.fire){
//Do stuff
} else if (element2 == Elements.water){
// Do stuff
} else {
// Do stuff
}
} else if (element2 == Elements.water){...etc...}
}
那僅用於火元素!
我搜索了一會兒,並查看了類似的SO問題,但不確定如何提出問題。 我發現的只是諸如“比對Enum更快的'=='或'.Equals()'之類的問題,這是完全不同的。
是否有捷徑可尋? 我已經在單獨的Manager中處理了這些條件,但仍然讓我感到惱火。
編輯:元素的組合始終具有相同的結果。 因此,火+水= X,水+火= X也是如此。
public void ElementCollisionExample(Elements element1, Elements element2)
{
// Do nothing on equal elements
if (element1 == element2) return;
switch (element1)
{
case Elements.fire when element2 == Elements.water:
case Elements.water when element2 == Elements.fire:
// Do stuff
break;
case Elements.fire when element2 == Elements.earth:
case Elements.earth when element2 == Elements.fire:
// Do stuff
break;
case Elements.water when element2 == Elements.earth:
case Elements.earth when element2 == Elements.water:
// Do stuff
break;
}
}
已更新: element1
和element2
順序無關緊要。 也忽略了相等的元素。
假設元素的組合順序無關緊要,則可以將枚舉視為一個位字段,即一組標志-這樣就可以將它們組合在一起,從而實現簡單的switch
。 例如:
[Flags]
public enum Elements
{
none = 0b0000_0000_0000,
fire = 0b0000_0000_0001,
water = 0b0000_0000_0010,
earth = 0b0000_0000_0100
};
public void ElementCollisionExample(Elements element1, Elements element2)
{
switch (element1 | element2)
{
case Elements.fire | Elements.water:
Console.WriteLine("The fire is extinguished");
break;
case Elements.earth | Elements.fire:
Console.WriteLine("The earth goes black");
break;
}
}
一種選擇是擁有可以調用的動作字典。 例如:
public class ElementActionFactory
{
// Somewhere to keep our actions, using tuple to pair up elements
private Dictionary<(Elements, Elements), Action> _elementActions;
public ElementActionFactory()
{
// Initialise the action dictionary
_elementActions = new Dictionary<(Elements, Elements), Action>
{
{(Elements.Fire, Elements.Fire), FireAndFire},
{(Elements.Fire, Elements.Water), FireAndWater},
{(Elements.Fire, Elements.Earth), FireAndEarth},
// etc.
};
}
public void Invoke(Elements element1, Elements element2)
{
// Try to get the action, and if we don't find it...
if (!_elementActions.TryGetValue((element1, element2), out var action))
{
// reverse the arguments and try again - this assumes the order is not important
if (!_elementActions.TryGetValue((element2, element1), out action))
{
return; //No action was found
}
}
// Actually run the method now
action.Invoke();
}
public void FireAndFire()
{
Console.WriteLine("Fire And Fire");
}
public void FireAndWater()
{
Console.WriteLine("Fire And Water");
}
public void FireAndEarth()
{
Console.WriteLine("Fire And Earth");
}
}
要使用它,它很簡單:
var elementActionFactory = new ElementActionFactory();
var element1 = Elements.Fire;
var element2 = Elements.Water;
elementActionFactory.Invoke(element1, element2);
對於清潔代碼,我建議使用復雜的開關...
Elements x, y;
switch (x)
{
case Elements.fire:
switch (y)
{
case Elements.fire:
break;
case Elements.water:
break;
case Elements.earth:
break;
}
break;
case Elements.water:
switch (y)
{
case Elements.fire:
break;
case Elements.water:
break;
case Elements.earth:
break;
}
break;
case Elements.earth:
switch (y)
{
case Elements.fire:
break;
case Elements.water:
break;
case Elements.earth:
break;
}
break;
}
使用元組,可以避免嵌套ifs:
public void ElementCollisionExample(Elements element1, Elements element2)
{
Tuple<Elements,Elements> elements = Tuple.Create(element1,element2);
if(elements.Equals(Tuple.Create(Elements.fire, Elements.earth))
{
//do something
}
else if(elements.Equals(Tuple.Create(Elements.fire, Elements.water))
{
// do something
}
// and so on
}
如果創建單獨的函數,則可以進一步簡化它:
public void ElementCollisionExample(Elements element1, Elements element2)
{
Tuple<Elements,Elements> elements = Tuple.Create(element1,element2);
if(CompareElements(elements, Elements.fire, Elements.earth))
{
//do something
}
else if(CompareElements(elements, Elements.fire, Elements.water))
{
// do something
}
// and so on
}
private bool CompareElements(Tuple<Elements,Elements> actual, Elements expected1, Elements expected2)
{
return actual.Equals(Tuple.Create(expected1, expected2));
}
我發現枚舉鏈接到整數。 因此,就我而言,我可以使用以下方法:
if ((int)element1 + (int)element2 == 3){
//Do stuff
}
在這種情況下,水(1)和土(2)的任何組合都將導致3,並觸發條件。
感謝每個人使用不同的方法,這將對無法使用我的方法找到該問題的人有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.