私のアプリケーションでは、次のようなものがあります。
public enum Locations {
LocationA,
LocationB,
LocationC
}
private List<Locations> _myLocations;
public Int64 PackedLocations {
get {
return PackEnumList(this._myLocations);
}
}
つまり、列挙型 (int に基づく)、それらの列挙値のリスト、およびこれまで省略したメソッドの結果を返す読み取り専用プロパティです。
そのメソッド PackEnumList は、対応する列挙値が一意の列挙値のリストで選択されたかどうかを各 BIT が示す 64 ビット整数を提供することを目的としています。したがって、上記の例では、_myLocations に {Locations.LocationA} という 1 つのアイテムしかない場合、結果は 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;
}