kzen.dev
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
Ronnie Overby
Ronnie Overby
Вопрос

Как передать несколько значений перечисления в C#?

Иногда при чтении чужого кода на C# я вижу метод, который принимает несколько значений перечислений в одном параметре. Я всегда думал, что это довольно аккуратно, но никогда не изучал этот вопрос.

Теперь я думаю, что мне это может понадобиться, но не знаю, как это сделать.

  1. настроить сигнатуру метода, чтобы он принимал это
  2. работать со значениями в методе
  3. определить перечисление

для достижения такого рода вещей.


В моей конкретной ситуации я хотел бы использовать System.DayOfWeek, который определяется как:
[Serializable]
[ComVisible(true)]
public enum DayOfWeek
{ 
    Sunday = 0,   
    Monday = 1,   
    Tuesday = 2,   
    Wednesday = 3,   
    Thursday = 4,   
    Friday = 5,    
    Saturday = 6
}

Я хочу иметь возможность передавать одно или несколько значений DayOfWeek в мой метод. Смогу ли я использовать это конкретное перечисление в его нынешнем виде? Как мне сделать три вещи, перечисленные выше?

111 2009-06-23T00:40:53+00:00 10
Ronnie Overby
Ronnie Overby
Редактировал вопрос 23-го июня 2009 в 1:20
Программирование
c#
enums
Решение / Ответ
Reed Copsey
Reed Copsey
23-го июня 2009 в 12:41
2009-06-23T00:41:57+00:00
Дополнительно
Источник
Редактировать
#9188591

Когда вы определяете перечисление, просто припишите к нему [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 был указан в виде флагов (или ублюдочный язык не предназначен для этого).

Reed Copsey
Reed Copsey
Редактировал ответ 23-го июня 2009 в 1:05
172
0
 Tillito
Tillito
13-го апреля 2011 в 11:56
2011-04-13T23:56:21+00:00
Дополнительно
Источник
Редактировать
#9188600

Я думаю, что более элегантное решение-использовать 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);
    }
76
0
 Jacob
Jacob
23-го июня 2009 в 12:46
2009-06-23T00:46:44+00:00
Дополнительно
Источник
Редактировать
#9188593

Я поддерживаю ответ Рида. Однако при создании перечисления вы должны указать значения для каждого члена перечисления, чтобы получилось своего рода битовое поле. Например:

[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.
}
 Jacob
Jacob
Редактировал ответ 23-го июня 2009 в 1:06
23
0
Robert Paulson
Robert Paulson
23-го июня 2009 в 2:11
2009-06-23T02:11:49+00:00
Дополнительно
Источник
Редактировать
#9188599

В моей конкретной ситуации, я бы как использовать систему.День недели

Вы не можете использовать систему.День недели как[флаги]перечисление, потому что вы не имеете никакого контроля над ним. Если вы хотите иметь метод, который принимает несколькодень недели, то вам придется использоватьпараметры` сайта

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 );

В противном случае вы можете создать свой собственный [флаги] перечисление, как это изложено множество других ответчиков и использовать побитовое сравнение.

11
0
 Tetraneutron
Tetraneutron
23-го июня 2009 в 12:51
2009-06-23T00:51:31+00:00
Дополнительно
Источник
Редактировать
#9188595
[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
  }
}
9
0
 Rony
Rony
23-го июня 2009 в 12:51
2009-06-23T00:51:25+00:00
Дополнительно
Источник
Редактировать
#9188594
[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();
        }
3
0
 statenjason
statenjason
23-го июня 2009 в 12:52
2009-06-23T00:52:37+00:00
Дополнительно
Источник
Редактировать
#9188596

Отметьте ваши перечисления с атрибут [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");
3
0
 Dan
Dan
23-го июня 2009 в 12:58
2009-06-23T00:58:06+00:00
Дополнительно
Источник
Редактировать
#9188597

Рид Copsey правильно и я бы добавил в оригинальный пост, если бы я мог, но я не могу так, Я'будете иметь, чтобы вместо того, чтобы ответить.

Его опасно просто использовать [флаги] на любой старой перечисление. Я считаю, что вам надо явно менять значения перечисления полномочия двух при использовании флагов, чтобы избежать столкновения в ценностях. См. В руководство по атрибут flagsattribute и enum.

2
0
Ronnie Overby
Ronnie Overby
23-го июня 2009 в 1:41
2009-06-23T01:41:37+00:00
Дополнительно
Источник
Редактировать
#9188598

С помощью опубликованных ответов и такие:

  1. Класс атрибут flagsattribute (Посмотрите на сравнение, используя и не используя [флаги] атрибут)
  2. Атрибут В Enum Флаги

Я чувствую, что это очень хорошо понимают.

Спасибо.

 Community
Community
Редактировал ответ 23-го мая 2017 в 10:31
0
0
Andrew Siemer
Andrew Siemer
23-го июня 2009 в 12:45
2009-06-23T00:45:18+00:00
Дополнительно
Источник
Редактировать
#9188592

Что-то в этом роде должно показать, что вы ищете:

[Flags]
public enum SomeName
{
    Name1,
    Name2
}

public class SomeClass()
{
    public void SomeMethod(SomeName enumInput)
    {
        ...
    }
}
-3
0
Похожие сообщества 6
Microsoft Stack Jobs
Microsoft Stack Jobs
2 414 пользователей
Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks
Открыть telegram
С#
С#
2 330 пользователей
Стараемся не флудить. Пишем по делу. Правила: https://t.me/professorweb/430450 Для флуда @svoboda_obsh
Открыть telegram
CODE BLOG / C#
CODE BLOG / C#
1 763 пользователей
Чат для .NET разработчиков и C# программистов. По всем вопросам: @shwanoff Youtube-канал: https://youtube.com/codeblog Основной канал: @codeblog Вконтакте: https://vk.com/codeblog Правила: https://t.me/codeblog_csharp/246972 Вакансии по тегу #work
Открыть telegram
var chat = new Chat();
var chat = new Chat();
1 428 пользователей
Обсуждение вопросов по .NET Правила чата – https://blog.devdigest.today/chat-rules Чат для флуда – https://t.me/+zwxI91RGG6s2YzAy
Открыть telegram
C#/.NET Для Новичков
C#/.NET Для Новичков
293 пользователей
Группа создана для тех, кто изучает язык программирования C#. Верховный главнокомандующий: @BlackDeveloper Оффтоп - разрешен в меру, реклама - бан.
Открыть telegram
ext
ext
31 пользователей
Общение на темы YouTube канала и программирования. Вакансии не размещаем. Основной канал: @extremecode
Открыть telegram
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Ilya Smirnov
Зарегистрирован 2 дня назад
2
Денис Васьков
Зарегистрирован 3 дня назад
3
Dima Patrushev
Зарегистрирован 6 дней назад
4
sirojidddin otaboyev
Зарегистрирован 2 недели назад
5
Елена Гайдамамакинат
Зарегистрирован 2 недели назад
ID
JA
KO
RU
© kzen.dev 2023
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией