用枚举保存状态是很方便的 利用位运算可以简洁明了
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
[Flags]
public enum TestState
{
aaa = 1,//0001
bbb = 2,//0010
ccc = 20,//0011
ddd = 4,//0100
eee = 7,//0111
fff = 8,//1000
ggg = 12,//1100
}
[Flags]
public enum StateMunte
{
金 = 0x0001,
木 = 0x0002,
水 = 0x0004,
火 = 0x0008,
土 = 0x0010,
生 = 0x0020,
旦 = 0x0040,
净 = 0x0080,
末 = 0x0100,
丑 = 0x0200
}
[Flags]
public enum StateBin
{
金 = 1,
木 = 1 << 1,
水 = 1 << 2,
火 = 1 << 3,
土 = 1 << 4,
生 = 1 << 5,
旦 = 1 << 6,
净 = 1 << 7,
末 = 1 << 8,
丑 = 1 << 9,
}
public class TestNum : MonoBehaviour
{
TestState testState = TestState.bbb;//不需要用new关键字
TestState stateCom;//不需要用new关键字
TestState statecccggg;//
TestState stateeeefff;//
StateMunte stateMunte;
StateBin stateBin;
StateMunte munteCom;
void Start()
{
Debug.Log("testState:" + testState);//print:testState:bbb
stateCom = TestState.aaa | TestState.bbb;//| &是做位运算,也是二进制运算1|2就是0001|0010 →0011=3,3→ccc
Debug.Log("stateCom:" + stateCom);//print:stateCom:ccc
stateCom = TestState.aaa | TestState.ddd;//0001|0100→ 0101=5,如果没有flags标记,5在enum列表中没有对应的话,debug出来的是数字5, enum 本就是 int值类型,在标记flags时,如果5能够每拆解成对应的枚举状态,那就会被拆解
Debug.Log("stateCom:" + stateCom);//print:stateCom:aaa, ddd
stateCom = TestState.bbb & TestState.ccc;//0010&0011→0010
Debug.Log("stateCom:" + stateCom);//print:stateCom:bbb
stateCom = (TestState)5;
Debug.Log("(TestState)5:" + stateCom);//print:(TestState)5:aaa, ddd
stateCom = TestState.bbb | TestState.ccc;//0010|0011
Debug.Log("stateCom:" + stateCom);//print:stateCom:ccc
statecccggg = TestState.ccc | TestState.ggg;//0011|1100→1111=15;
stateeeefff = TestState.eee | TestState.fff;//0111|1000→1111=15;
Debug.Log("statecccggg:" + statecccggg);//print:statecccggg:ccc, ggg
Debug.Log("stateeeefff:" + stateeeefff);//print:statecccggg:ccc, ggg;两者打印结果相同可见,枚举类型做位运算其实就是对int进行位运算,算出来的结果也是int,然后转换成枚举,在没有flags的情况下若没有直接对应的状态值,则会输出为数字,在有flags的情况下,若没有直接应的状态值,则会检索枚举中能组合成该值得状态组合.按两者打印相同的结果来看,检索是有检索规则的,按对应int值从小到大检索,匹配成功则确定了枚举值;对此检索规则产生怀疑:有可能是按照枚举状态在列表中的位置来检索的,我调整过枚举对应的位置,把 eee放在ccc的前面,但结果是一样的,所以一个int的值转换成在flags的枚举若没有直接对应的状态则会考虑分解判断.目前可分解成两个,那是否可分解成3个或更多,下面来做测试.在上面枚举1011的状态时没有的,但可以由0001 0010 1000组成,也可以由0011 1000组成.1011=11
Debug.Log(" (TestState)11:" + (TestState)11);//print: (TestState)11:ccc, fff;当我把ccc的值调整,让0011不存在,0011 1000组合也就不成立了, 然后再测试 print:(TestState)11:aaa, bbb, fff; 由此可见 分解考虑会先从数量少的开始匹配.如果没有则加深检测
Debug.Log("```````````````````````````````````华丽的分割线`````````````````````````````````");
Type type = typeof(StateMunte);
FieldInfo[] fieldInfos = type.GetFields();
for (int i = 0; i < fieldInfos.Length; i++)
{
Debug.Log(string.Format(" fieldInfos[{0}]:{1}", i, fieldInfos[i]));
Debug.Log(string.Format(" fieldInfos[{0}].name:{1}", i, fieldInfos[i].Name));
}
Debug.Log("```````````````````````````````````华丽的分割线`````````````````````````````````");
stateMunte = StateMunte.木 | StateMunte.水 | StateMunte.火 | StateMunte.土;
stateBin = StateBin.丑;
Debug.Log("stateMunte:" + stateMunte);
Debug.Log("(int)stateMunte:" + (int)stateMunte);
Debug.Log("stateBin:" + stateBin);
Debug.Log("(int)stateBin:" + (int)stateBin);
munteCom = StateMunte.水 | StateMunte.火 | StateMunte.土;
Debug.Log(" munteCom.CompareTo(stateMunte):" + munteCom.CompareTo(stateMunte));//比大小
//munteCom.HasFlag();
stateMunte.Equals(munteCom & stateMunte);
if (stateMunte.Equals(munteCom & stateMunte))
{
Debug.Log(true);
}
else
{
Debug.Log(false);
}
}
}