Вариант 3 кажется мне хорошей идеей. Имейте в виду, что перечисления .NET не будут генерировать исключения, если для них заданы неопределенные значения, поэтому ничто не мешает вашим пользователям говорить:
PrintDriversLicenseStatus(42);
... где PrintDriversLicenseStatus
принимает DriversLicenseFlags
в качестве аргумента.
Таким образом, вам все равно придется проверять свои входные данные, чтобы убедиться, что они являются определенным значением.
Редактировать
Еще один вариант для вашего рассмотрения: создайте специальный внутренний перечислимый класс и приведите к нему аргументы для внутреннего использования:
[Flags]
public enum DriversLicenseFlagsInternal
{
None = 0,
Suspended = 1 << 1,
Revoked = 1 << 2,
Restored = 1 << 3,
SuspendedAndRestored = Suspended | Restored,
RevokedAndRestored = Revoked | Restored,
}
[Flags]
internal enum DriversLicenseFlags
{
None = DriversLicenseFlagsInternal.None,
Suspended = DriversLicenseFlagsInternal.Suspended,
Revoked = DriversLicenseFlagsInternal.Revoked,
SuspendedAndRestored = DriversLicenseFlagsInternal.SuspendedAndRestored,
RevokedAndRestored = DriversLicenseFlagsInternal.RevokedAndRestored,
}
public void DoSomething(DriversLicenseFlags arg)
{
var argAsInternal = (DriversLicenseFlagsInternal) arg;
// or var argAsInternal = Util.CheckDefinedDriversLicense(arg);
}
Не уверен, что это лучше, но может показаться менее хакерским.