Регистрация Главная Сообщество
Сообщения за день Справка Регистрация

Ответ
 
Опции темы
Старый 01.03.2016, 21:25   #1
 Разведчик
Аватар для HideFebruary
 
HideFebruary лучик света в грозовом небеHideFebruary лучик света в грозовом небеHideFebruary лучик света в грозовом небеHideFebruary лучик света в грозовом небеHideFebruary лучик света в грозовом небеHideFebruary лучик света в грозовом небеHideFebruary лучик света в грозовом небе
Регистрация: 25.02.2016
Сообщений: 5
Популярность: 771
Сказал(а) спасибо: 0
Поблагодарили 5 раз(а) в 5 сообщениях
 
По умолчанию Monads [0]

Если ты, дорогой читатель, еще не знаешь что такое методы расширения - бросай все свои дела и беги изучай! Ведь это невероятно удобная и лакончиная возможность добавить свою логику в чужой(!) класс.

Это вводная статья по монадам, зачем это нужно, что это такое и при чем тут расширения - далее по тексту.

Возьмем в пример очень неудобный метод IsNullOrWhiteSpace класса String, это статический метод проверяющий есть ли в строке что-нибудь. Проблема этого метода в том, что он находится не в экземпляре, а значит, каждый раз перед тем как его вызвать нужно обращаться к классу String и передать строку в метод, пример:

Код:
var str = "   ";
if ( String.IsNullOrWhiteSpace ( str ) ) WriteLine ( "Invalide argument" );
Было бы куда логичней, если бы данный метод находился в экземпляре и его вызов происходил следующим образом:

Код:
var str = "   ";
if ( str.IsNullOrWhiteSpace () ) WriteLine ( "Invalide argument" );
Сразу видно как строка сократилась, этот код более читабельный и лаконичный, без лишних обращений.

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

Цитата:
Методы расширения позволяют "добавлять" методы в существующие типы без создания нового производного типа, перекомпиляции или иного изменения исходного типа. Методы расширения представляют собой особую разновидность статического метода, но вызываются так же, как методы экземпляра в расширенном типе.Для клиентского кода, написанного на языках C# и Visual Basic, нет видимого различия между вызовом метода расширения и вызовом методов, фактически определенных в типе.

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

Код:
public static class StringExtension
{
   public static bool IsNullOrWhiteSpace ( this String str )
      => String.IsNullOrWhiteSpace ( str );
}
Теперь можно использовать конструкцию такого типа:
Код:
var b = "   ".IsNullOrWhiteSpace ();
Это решило нашу проблему, мы реализовали локальную инверсию, от чего код стал более удобным. Конечно же это слабый пример в пользу методов расширений, ведь никому хуже не станет если использовать стандартный вариант, тем более он будет работать гораздо быстрей. Но поверь, дорогой друг, это знание тебе еще ни раз пригодится!

Что бы доказать, что предоставленный подход действительно имеет право на жизнь ( а он имеет, ведь подумайте, эту возможность зачем-то ввели сами разработчики ), я покажу более крутой пример!

Помните мою предыдушую статью? ( конечно помните, она же вызвала такой ажиотаж ) http://zhyk.ru/forum/showthread.php?t=1064388

Так вот, сделаем немного другую реализацию данного класса. Добавим метод расширения к перечислению Keys, которым будем проверять нажата ли кнопка.

Создадим статический класс и добавим в него такой статический метод:
Код:
public static bool IsPressing ( this Keys key )
   => GetAsyncKeyState ( key ) == PRESSING;
Метод GetAsyncKeyState и константу PRESSING смотри в предыдущей статье, либо в конце темы!

Теперь мы можем проверить легко, нажата ли какая-нибудь из клавиш подобным образом:
Код:
var b = Keys.A.IsPressing ();
Либо получить таким образом все нажатые клавиши и отобразить их:
Код:
var pressingKeys = Enum.GetValues( typeof( Keys ) ).Cast<Keys>().Where( key => key.IsPressing() ).ToList();
pressingKeys.ForEach ( key => WriteLine ( key.ToString () ) );
Круто ведь, неправда ли?!

Мы можем пойти дальше и вообще миновать перечисление Keys, добавив этот метод расширения еще и к классу String, что бы по названию клавиши определить нажата ли она! Понимаю, что это вакханалия, но ведь весело.

Добавим в прошлый статический класс StringExtension такой метод:
Код:
public static bool KeyIsPressing( this String str )
{
   var names = Enum.GetNames( typeof( Keys ) );
   if ( !names.Contains ( str ) ) return false;

   var value = (Keys) Enum.Parse( typeof( Keys ), str );
   return value.IsPressing ();
}
Данный метод делает следующее:
  • var names = Enum.GetNames( typeof( Keys ) ); - берет у перечисления имена всех клавиш
  • if ( !names.Contains ( str ) ) return false; - если такой клавиши как мы указали не существует, то возвращаем ложь. Ведь если такой клавиши нет, то она и не нажата, логично же.
  • var value = (Keys) Enum.Parse( typeof( Keys ), str ); - получаем значение данной клавиши
  • return value.IsPressing (); - используем метод расширения у перечисления Keys который написали ранее и он уже вернет результат, нажата ли клавиша которую мы написали.

Использовать это можно так:
Код:
if ( "A".KeyIsPressing () ) WriteLine ( "A is pressing!!!" );
Засуньте в цикл и веселитесь.

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

В спойлере исходники классов из данной статьи:
Спойлер

Следующая статья: Monads [1] = Do

Последний раз редактировалось HideFebruary; 06.03.2016 в 16:23.
  Ответить с цитированием
Пользователь сказал cпасибо:
Sinyss (23.05.2016)
Ответ

Метки
c sharp, dotnet, extension, monads


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Заявление об ответственности / Список мошенников

Часовой пояс GMT +4, время: 22:49.

Пишите нам: [email protected]
Copyright © 2024 vBulletin Solutions, Inc.
Translate: zCarot. Webdesign by DevArt (Fox)
G-gaMe! Team production | Since 2008
Hosted by GShost.net