Иногда при чтении чужого кода на C# я вижу метод, который принимает несколько значений перечислений в одном параметре. Я всегда думал, что это довольно аккуратно, но никогда не изучал этот вопрос.
Теперь я думаю, что мне это может понадобиться, но не знаю, как это сделать.
для достижения такого рода вещей.
[Serializable]
[ComVisible(true)]
public enum DayOfWeek
{
Sunday = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6
}
Я хочу иметь возможность передавать одно или несколько значений DayOfWeek в мой метод. Смогу ли я использовать это конкретное перечисление в его нынешнем виде? Как мне сделать три вещи, перечисленные выше?
Когда вы определяете перечисление, просто припишите к нему [Flags], установите значения в степени двойки, и оно будет работать таким образом.
Больше ничего не меняется, кроме передачи нескольких значений в функцию.
Например:
[Flags]
enum DaysOfWeek
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64
}
public void RunOnDays(DaysOfWeek days)
{
bool isTuesdaySet = (days & DaysOfWeek.Tuesday) == DaysOfWeek.Tuesday;
if (isTuesdaySet)
//...
// Do your work here..
}
public void CallMethodWithTuesdayAndThursday()
{
this.RunOnDays(DaysOfWeek.Tuesday | DaysOfWeek.Thursday);
}
Более подробную информацию можно найти в MSDN'документации по типам перечислений.
Редактирование в ответ на дополнения к вопросу.
Вы не сможете использовать этот enum как есть, если только вы не хотите сделать что-то вроде передачи его как массива/коллекции/массива параметров. Это позволит вам передавать несколько значений. Синтаксис флагов требует, чтобы Enum был указан в виде флагов (или ублюдочный язык не предназначен для этого).
Я думаю, что более элегантное решение-использовать HasFlag():
[Flags]
public enum DaysOfWeek
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64
}
public void RunOnDays(DaysOfWeek days)
{
bool isTuesdaySet = days.HasFlag(DaysOfWeek.Tuesday);
if (isTuesdaySet)
{
//...
}
}
public void CallMethodWithTuesdayAndThursday()
{
RunOnDays(DaysOfWeek.Tuesday | DaysOfWeek.Thursday);
}
Я поддерживаю ответ Рида. Однако при создании перечисления вы должны указать значения для каждого члена перечисления, чтобы получилось своего рода битовое поле. Например:
[Flags]
public enum DaysOfWeek
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64,
None = 0,
All = Weekdays | Weekend,
Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday,
Weekend = Sunday | Saturday,
// etc.
}
В моей конкретной ситуации, я бы как использовать систему.День недели
Вы не можете использовать систему.День недели как[флаги]перечисление, потому что вы не имеете никакого контроля над ним. Если вы хотите иметь метод, который принимает несколько
день недели, то вам придется использовать
параметры` сайта
void SetDays(params DayOfWeek[] daysToSet)
{
if (daysToSet == null || !daysToSet.Any())
throw new ArgumentNullException("daysToSet");
foreach (DayOfWeek day in daysToSet)
{
// if( day == DayOfWeek.Monday ) etc ....
}
}
SetDays( DayOfWeek.Monday, DayOfWeek.Sunday );
В противном случае вы можете создать свой собственный [флаги]
перечисление, как это изложено множество других ответчиков и использовать побитовое сравнение.
[Flags]
public enum DaysOfWeek
{
Mon = 1,
Tue = 2,
Wed = 4,
Thur = 8,
Fri = 16,
Sat = 32,
Sun = 64
}
Вы должны указать номера, и прирост их, как это, потому что это хранение ценностей в побитовую моды.
Затем просто определить свой метод, чтобы взять это перечисление
public void DoSomething(DaysOfWeek day)
{
...
}
и называть его сделать что-то подобное
DoSomething(DaysOfWeek.Mon | DaysOfWeek.Tue) // Both Monday and Tuesday
Чтобы проверить, если одно из значений перечисления, был включен проверить их, используя побитовые операции, как
public void DoSomething(DaysOfWeek day)
{
if ((day & DaysOfWeek.Mon) == DaysOfWeek.Mon) // Does a bitwise and then compares it to Mondays enum value
{
// Monday was passed in
}
}
[Flags]
public enum DaysOfWeek{
Sunday = 1 << 0,
Monday = 1 << 1,
Tuesday = 1 << 2,
Wednesday = 1 << 3,
Thursday = 1 << 4,
Friday = 1 << 5,
Saturday = 1 << 6
}
вызвать метод в таком формате
Имя_метода(DaysOfWeek.Вторник | DaysOfWeek.Четверг);
Осуществлять EnumToArray способ, чтобы получить параметры, передаваемые
private static void AddEntryToList(DaysOfWeek days, DaysOfWeek match, List<string> dayList, string entryText) {
if ((days& match) != 0) {
dayList.Add(entryText);
}
}
internal static string[] EnumToArray(DaysOfWeek days) {
List<string> verbList = new List<string>();
AddEntryToList(days, HttpVerbs.Sunday, dayList, "Sunday");
AddEntryToList(days, HttpVerbs.Monday , dayList, "Monday ");
...
return dayList.ToArray();
}
Отметьте ваши перечисления с атрибут [flags]. Также убедитесь, что все ваши ценности являются взаимоисключающими (два значения могут'т добавить до равного другим) как 1,2,4,8,16,32,64 в вашем случае
[Flags]
public enum DayOfWeek
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64
}
Когда у вас есть метод, который принимает DayofWeek перечисление использовать побитовый оператор OR ( | ), чтобы использовать несколько элементов вместе. Например:
MyMethod(DayOfWeek.Sunday|DayOfWeek.Tuesday|DayOfWeek.Friday)
Чтобы проверить, если параметр содержит конкретного участника, использовать побитовое и оператор (&ампер;) с членом вы проверяете наличие.
if(arg & DayOfWeek.Sunday == DayOfWeek.Sunday)
Console.WriteLine("Contains Sunday");
Рид Copsey правильно и я бы добавил в оригинальный пост, если бы я мог, но я не могу так, Я'будете иметь, чтобы вместо того, чтобы ответить.
Его опасно просто использовать [флаги] на любой старой перечисление. Я считаю, что вам надо явно менять значения перечисления полномочия двух при использовании флагов, чтобы избежать столкновения в ценностях. См. В руководство по атрибут flagsattribute и enum.
С помощью опубликованных ответов и такие:
Я чувствую, что это очень хорошо понимают.
Спасибо.
Что-то в этом роде должно показать, что вы ищете:
[Flags]
public enum SomeName
{
Name1,
Name2
}
public class SomeClass()
{
public void SomeMethod(SomeName enumInput)
{
...
}
}