Для каждого цикла через DayOfWeek перечисление начать в понедельник?

Я повторяю через DayOfWeek Enum следующее:

foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek)))
{
 // Add stuff to a list 
}

И моя проблема в том, что я хотел бы, чтобы мой enum начинался с понедельника вместо воскресенья.

Я попытался сделать:

CultureInfo ci = Thread.CurrentThread.CurrentCulture;
ci.DateTimeFormat.FirstDayOfWeek = DayOfWeek.Monday;

Но цикл foreach все еще начинался с воскресенья.

Как я могу это сделать?

Моей последней идеей было бы переупорядочить мой итоговый список в порядке, который я хочу, но это будет означать больше итераций.

Благодаря !

Ответ 1

Это невозможно, потому что настройка культуры не изменяет тот факт, что enum DayOfWeek определяется как таковое:

public enum DayOfWeek {
    Sunday = 0,
    Monday = 1,
    Tuesday = 2,
    Wednesday = 3,
    Thursday = 4,
    Friday = 5,
    Saturday = 6,
}

Однако вы можете пропустить первую запись и добавить ее позже.. возможно, вот так:

foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek))
                              .OfType<DayOfWeek>()
                              .ToList()
                              .Skip(1)) {
    list.Add(day.ToString());
}
list.Add(DayOfWeek.Sunday.ToString());

Ответ 2

Один вызов OrderBy может заказать их по желанию. Невозможно изменить порядок вызова Enum.GetValues.

var daysOfWeek = Enum.GetValues(typeof(DayOfWeek))
    .OfType<DayOfWeek>()
    .OrderBy(day => day < DayOfWeek.Monday);

Ответ 3

Используйте цикл for и оператор modulo (%):

DayOfWeek day;
for( int i = 0 ; i < 7 ; i++ )
{
    day = (DayOfWeek) ((i + 1) % 7);
    // Add stuff to a list
}

Если вы хотите использовать этот цикл для переключения другого перечисления, вы всегда можете заменить номер 7 переменной, инициализированной следующим образом:

int length = Enum.GetValues(typeof(DayOfWeek)).Length;

Вы даже можете написать метод сдвига любого перечисления, считая, что это перечисление имеет все значения между 0, 1,..., n:

static IEnumerable<TEnum> Shift<TEnum>(int offset) where TEnum : struct
{
    int length = Enum.GetValues(typeof(TEnum)).Length;
    for( int i = 0 ; i < length ; i++ )
    {
        yield return (TEnum) (object) ((i + offset) % length);
    }
}

Ответ 4

Начните с пользовательского IComparer<DayOfWeek>:

public class DayOfWeekComparer : IComparer<DayOfWeek> {
    public int Compare(DayOfWeek x, DayOfWeek y) {
        return ModifyDayOfWeek(x).CompareTo(ModifyDayOfWeek(y));
    }

    private static int ModifyDayOfWeek(DayOfWeek x) {
        // redefine Sunday so it appears at the end of the ordering
        return x == DayOfWeek.Sunday ? 7 : (int)x;
    }
}

Затем:

foreach(DayOfWeek day in Enum.GetValues(typeof(DayOfWeek))
                             .OfType<DayOfWeek>()
                             .OrderBy(x => x, new DayOfWeekComparer())) {
    // will see Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}

Изменить для добавления:

Собственно, даже это слишком сложно, так же красиво. Почему бы вам просто не поставить

static IEnumerable<DayOfWeek> DaysOfWeek {
    get {
        yield return DayOfWeek.Monday;
        yield return DayOfWeek.Tuesday;
        yield return DayOfWeek.Wednesday;
        yield return DayOfWeek.Thursday;
        yield return DayOfWeek.Friday;
        yield return DayOfWeek.Saturday;
        yield return DayOfWeek.Sunday;
   }
}

где-нибудь, где угодно, и просто покончить с этим! KISS !

Ответ 5

Enum.GetValues возвращает элементы, которые сортируются по двоичным значениям констант перечисления (см. Примечания в MSDN). Перечисление DayOfWeek определяется следующим образом:

public enum DayOfWeek
{
    Sunday = 0,
    Monday = 1,
    Tuesday = 2,
    Wednesday = 3
    Thursday = 4,
    Friday = 5,
    Saturday = 6,
}

Как вы можете видеть, Monday определяется как 1 а Sunday - 0. Таким образом, вы не можете заставить метод Enum.GetValues вернуться в Monday до Sunday.