Как стать автором
Обновить
54
-3

Пользователь

Отправить сообщение
Я это вижу так, но ваш вопрос лучше задать архитекторам языка Питон, зачем ещё такое могло понадобиться? )
Ок, назовём это всё интеллектуальным упражнением, а не математической моделью ;)
Да, снова моя неточность. Исправил, спасибо! Но теперь уж, думаю, всё точно :)
Почему же в реализации Питона хвост не включается? ) Кто-то тоже напутал?
Тогда воспринимайте это как абстрактную математическую конструкцию, которой пока ещё не нашлось применения :)

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

По крайней мере, как задачка для развития логики мышления, она очень подходит…
Я знаю, что вас не убедить :)

Но спасибо, что приняли участие и указали на неточность в статье!

Соглашусь с вами, что это больше напоминает способ нотации и понятие «пустой слайс» в нём не определено. Но и такая нотация даёт некоторые преимущества. Конечно, довольно просто добавить нужный флаг (useShift по умолчанию равный true) и в случае Slice(5, 5, false) возвращать вместо сдвига пустое значение, если это нужно.
Про пустую выборку я соврал, извините, будет один элемент.
Уже это исправил, надеюсь, теперь всё стало на свои места.

Словами по шестой, а в коде по седьмой?

По шестой включительно (или по седьмой, не включая, как в коде)

Спасибо, что внимательно читаете и обнауживаете неточности!
Наглядные примеры в статье. Конечно, каждый день таких необходимотей возникать не будет, но сдвиги элементов в массивах — распостранённое явление и, как видим, это частный случай выполнения «среза», поэтому логично и красиво обобщить эти операции в один метод, на мой взгляд.
метод не рассчитан на такие коллекции. это то же самое, как случайно вызвать Count(), ToList() или ToArray() у запроса с милионами результатов. вы же не отказываетесь от использования этих методов только из-за того, что они несут в себе такую потенциальную опасность повесить ваше приложение.
а он нужен?
вот так
Enumerable.Empty<T>()

теперь всё становится логично?
Спасибо, разобрались, заметили ошибку! Мой косяк, исправлю. Да, будет один элемент. Пустого результата нет.
Не знаю, как у вас, но в подавляющем большинстве случаев обрабатываются конечные коллекции. За всю мою практику ни разу не доводилось обрабатывать бесконечную. Разве что на собеседовании была задачка, как обнаружить возможную зацикленность в бесконечном однонаправленном списке.

Я же вас не спрашиваю, как вы вызовете метод Count() у бесконечной последовательности… Вопрос сродни вашему.
Насчёт же интуитивности, достаточно один раз принять зацикленность (замкнутость) коллекции и всё становится на свои места, причём автоматически устраняются многие противоречия, возникающие без этого положения, а функционал метода только расширяется ничего не утрачивая.
На вкус и цвет товарищей нет.
Возможно, да, это не совсем тот слайс, о котором вы думаете, но сам метод Slice не создаёт никаких копий, а только лишь выполняет итерацию. Назовём это модификацией, суть же очень схожа.

Шаг var items = collection as T[] ?? collection.ToArray() я оставил осознанно, поскольку метод расчитан в большинстве своём на материализованные коллекции, а если вас это пугает, то сделайте свою реализацию без отрицательных индексов и проверки длины. Не трудно.
Добро, согласен на ничью )
Довольно интересно наблюдать, как получают развитие некоторые схожие идеи, но разными путями.
Можете в двух словах описать, что умеет ваш MapReduce движок?
И ещё вопрос, допускаются ли в вашей реализации асинхронные обработчики у событий нотификации?

this[() => Text].PropertyChanged += async (sender, args) =>
{
       IsSaved = await server.SaveText(Text); 
};

Иногда очень полезно иметь такую возможность.
Ок, забудем это слово :)

Инвалидация контекстных команд происходит, например, следующим образом по изменению свойства:

            this[() => Kisses].PropertyChanged += (sender, args) =>
            {
                Context.Get("KissGirl").RaiseCanExecuteChanged();
                Context.Get("KissGuy").RaiseCanExecuteChanged();
            };

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

            this[() => Kisses].PropertyChanged += (sender, args) =>
            {
                if (Kesses < 10) return;
                Context.Get("KissGirl").RaiseCanExecuteChanged();
                Context.Get("KissGuy").RaiseCanExecuteChanged();
            };

Поскольку в некоторых случаях обработчик CanExecute вызывать затратно или излишне.

Контекстные команды очень похожи в использовании на RoutedCommands из WPF, по сути, это их упрощённая кроссплатформенная модель.

Интересно, у вас можно сделать что-то наподобие такого?

this[Context.Refresh].Executed += async (sender, args) =>
{
      try
      {
            IsBusy = true;
            User = await server.GetUserData(Login, Password);
      }
      finally
      {
            IsBusy = false;
      }
};

Имею в виду асинхронность async/await.
Рекомендую ещё эту идею в вашей библиотеке и для команд применить — очень красиво получается, если всё грамотно сделать. Собственно, исторически в аэро фремворке сначала появились эвокаторы команд, а только потом свойств :)

this[MediaCommands.Play].CanExecute += (sender, args) => args.CanExecute = IsStopped;
this[Context.Get("HelloCommand")].Executed += (sender, args) => MessageBox.Show("Hello!");

Это крутая фича для тех, у кого страсть к простоте и лаконичности кода.
Стоит отметить, что эвокаторы свойств в Aero Framework также поддерживают достаточно удобные способы как синхронной валидации свойств (IDataErrorInfo), так и асинхронной (INotifyDataErrorInfo). Выглядит подобным образом:

this[() => Mouse].ErrorsChanged += (sender, args) => HasErrors = !(5 < Mouse.Length && Mouse.Length < 20);
this[() => Mouse].ValidationRules += s => 5 < Mouse.Length && Mouse.Length < 20 ? null : "Invalid Length";
Существует ещё более лаконичный способ регистрации обработчиков:

this[() => Text].PropertyChanging += (o, args) => { ... };
this[() => Text].PropertyChanged += (o, args) => { ... };

Посмотрите эвокаторы свойств и команд в библиотеке Aero Framework, сама идея похожа на вашу.

Пример простой вьюмодели
    [DataContract]
    public class GuyViewModel : ContextObject, IExposable
    {
        [DataMember]
        public int Kisses
        {
            get { return Get(() => Kisses); }
            set { Set(() => Kisses, value); }
        }

        public void Expose()
        {
            var girlViewModel = Store.Get<GirlViewModel>();

            this[() => Kisses].PropertyChanged += (sender, args) =>
            {
                Context.Get("KissGirl").RaiseCanExecuteChanged();
                Context.Get("KissGuy").RaiseCanExecuteChanged();
            };

            this[Context.Get("KissGirl")].CanExecute += (sender, args) => 
                args.CanExecute = Kisses > girlViewModel.Kisses - 2;

            this[Context.Get("KissGirl")].Executed += (sender, args) => 
                girlViewModel.Kisses++;
        }
    }



Информация

В рейтинге
Не участвует
Зарегистрирован
Активность