在我的应用程序中,我有类似的东西:
public enum Locations {
LocationA,
LocationB,
LocationC
}
private List<Locations> _myLocations;
public Int64 PackedLocations {
get {
return PackEnumList(this._myLocations);
}
}
所以:一个枚举(由 int 支持)、这些枚举值的列表,以及一个只读属性,它返回我迄今为止遗漏的方法的结果。
该方法 PackEnumList 旨在给我一个 64 位整数,其中每个 BIT 表示是否在唯一枚举值列表中选择了相应的枚举值。因此,在我上面的示例中,如果 _myLocations 只有一项:{Locations.LocationA},则结果将为 1(二进制:...00001),如果我们随后将 Locations.LocationC 添加到该列表中,则结果将为 5(二进制:...000101)。实现现在并不重要(但我将在下面包含它以完成/兴趣/反馈),但该方法的签名是:
public Int64 PackEnumList(List<Enum> listOfEnumValues) {
...
}
当我编译时,我得到一个错误,“最好的重载方法......有一些无效的参数”。
我猜这是因为 _myLocations 被视为 int 值的列表,但我希望 PackEnumList() 能够工作,即使正在使用的枚举由其他东西支持,如果可能的话。
有没有更合适的方法来制作一个可以接受任何枚举的列表/集合的方法?
为了完整起见,这是我要做的其余部分(这些是静态的,因为它们在共享实用程序类中)。这些还完全未经测试(因为我在调用 pack 方法时无法克服编译错误),所以对它们持保留态度。可能有更好的方法来做到这一点,我这样做一半是为了解决一个有趣的问题,另一半是因为我认为这是一个有趣的问题。
public static Int64 PackEnumList(List<Enum> listOfEnumValues) {
BitArray bits = new BitArray(64, defaultValue: false);
foreach (var value in listOfEnumValues) {
// get integer value of each Enum in the List:
int val = Convert.ToInt32(value);
if (val >= 64) {
// this enum has more options than we have bits, so cannot pack
throw new Exception("Enum value out of range for packing: " + val.ToString());
}
bits[val] = true;
}
var res = new Int64[1];
bits.CopyTo(res, 0);
return res[0];
}
// (this method is a little farther from the ideal: the resulting list will need
// to be matched by the caller to the appropriate List of Enums by casting
// each Int32 value to the Enum object in the list)
public static List<Int32> UnpackEnumList(Int64 packedValue) {
string binaryString = Convert.ToString(packedValue, 2);
List<Int32> res = new List<Int32>();
for (int pos = 0; pos < binaryString.Length; pos++) {
if (binaryString[binaryString.Length - pos - 1] == '1') {
// bit is on
res.Add(pos);
}
}
return res;
}