Также смотрите обновления в конце вопроса ...
Учитывая следующую ситуацию:
[Flags]
enum SourceEnum
{
SNone = 0x00,
SA = 0x01,
SB = 0x02,
SC = 0x04,
SD = 0x08,
SAB = SA | SB,
SALL = -1,
}
[Flags]
enum DestEnum
{
DNone = 0x00,
DA = 0x01,
DB = 0x02,
DC = 0x04,
DALL = 0xFF,
}
Я хотел бы преобразовать один тип перечисления в другой и наоборот, основываясь на функции отображения, используя имена, такие как большой переключатель (), но так как это перечисление flags, мне трудно создать такую подпрограмму, чтобы она была универсальной .
По сути, я хочу что-то вроде следующего:
Пример # 1
SourceEnum source = SourceEnum.SA;
DestEnum dest = Map<Source, Dest> (source);
Assert.That (dest, Is.EqualTo (DestEnum.DA));
Пример # 2
SourceEnum source = SourceEnum.SA | SourceEnum.SB;
DestEnum dest = Map<Source, Dest> (source);
Assert.That (dest, Is.EqualTo (DestEnum.DA | DestEnum.DB));
Пример # 3
SourceEnum source = SourceEnum.SAB;
DestEnum dest = Map<Source, Dest> (source);
Assert.That (dest, Is.EqualTo (DestEnum.DA | DestEnum.DB));
Пример # 4
SourceEnum source = SourceEnum.SALL;
DestEnum dest = Map<Source, Dest> (source);
Assert.That (dest, Is.EqualTo (DestEnum.DALL));
Пример # 5
SourceEnum source = SourceEnum.SD;
var ex = Assert.Throws<Exception> (() => Map<Source, Dest> (source));
Assert.That (ex.Message, Is.EqualTo ("Cannot map SourceEnum.SD to DestEnum!"));
Функция Map () может принимать делегата для предоставления фактического отображения, но мне все еще нужно иметь несколько функций для помощи такому делегату с битами ...
DestEnum SourceToDestMapper (SourceEnum source)
{
// Switch cannot work with bit fields enumeration...
// This is to give the general idea...
switch (source)
{
case SourceEnum.SNone:
return DestEnum.DNone;
case SourceEnum.SA:
return DestEnum.DA;
case SourceEnum.SAB:
return DestEnum.DA | DestEnum.DB;
...
default:
throw new Exception ("Cannot map " + source.ToString() + " to DestEnum!");
}
}
РЕДАКТИРОВАТЬ: УТОЧНЕНИЕ
Может показаться, что значения определений перечисления соответствуют друг другу, но это не всегда так.
Например, это может быть:
enum SourceEnum
{
SA = 0x08,
SB = 0x20,
SC = 0x10,
SAB = SA | SB,
SABC = SA | SB | SC,
}
enum DestEnum
{
DA = 0x04,
DB = 0x80,
DC = 0x01,
DAB = DA | DB,
}
РЕДАКТИРОВАТЬ: Подробнее
Я ищу способ сделать пользовательское отображение флагов enum, не основанное на шаблонах имен. Однако имена используются в пользовательской функции сопоставления.
Я вполне мог бы иметь функцию SourceToDestMapper, пытающуюся сопоставить SA с DC, например ...
Основная проблема заключается в предоставлении функции SourceToDestMapper каждого флага источника И заботе о значениях флагов, имеющих несколько наборов битов ...
Например:
Наличие флага SourceEnum.SABC вызовет функцию SourceToDestMapper три раза, что приведет к следующему:
- SourceEnum.SA сопоставлен с DestEnum.DA
- SourceEnum.SB сопоставлен с DestEnum.DB
- SourceEnum.SC сопоставлен с DestEnum.DC
И в результате DestEnum будет: DestEnum.DA | DestEnum.DB | DestEnum.DC