Вот пример, чтобы прояснить, как все работает с GCC при использовании статических библиотек. Итак, предположим, что мы имеем следующий сценарий:
myprog.o
- содержащий функцию main()
, зависящую от libmysqlclient
libmysqlclient
- статично, ради примера (вы предпочтете разделяемую библиотеку, конечно, поскольку libmysqlclient
огромен); в /usr/local/lib
; и зависит от материала из libz
libz
(dynamic) Как мы это связываем? (Примечание: примеры компиляции на Cygwin с использованием gcc 4.3.4)
gcc -L/usr/local/lib -lmysqlclient myprog.o
# undefined reference to `_mysql_init'
# myprog depends on libmysqlclient
# so myprog has to come earlier on the command line
gcc myprog.o -L/usr/local/lib -lmysqlclient
# undefined reference to `_uncompress'
# we have to link with libz, too
gcc myprog.o -lz -L/usr/local/lib -lmysqlclient
# undefined reference to `_uncompress'
# libz is needed by libmysqlclient
# so it has to appear *after* it on the command line
gcc myprog.o -L/usr/local/lib -lmysqlclient -lz
# this works
Я думаю, что дополнительные методы помогают много, когда написание кода, если Вы добавляете дополнительные методы к основным типам, Вы получите их quicky в intellisense.
у меня есть поставщик формата к , форматируют размер файла . Для использования его, я должен записать:
Console.WriteLine(String.Format(new FileSizeFormatProvider(), "{0:fs}", fileSize));
Создание дополнительного метода я могу записать:
Console.WriteLine(fileSize.ToFileSize());
Инструмент для очистки и более простой.
Я думаю, что дополнительная справка методов пишет код, который является более четким.
Вместо того, чтобы поместить новый метод в Вашем классе, как Ваш предложенный друг, Вы выразились в пространстве имен ExtensionMethods. Таким образом Вы поддерживаете логический смысл порядка к Вашему классу. Методы, которые действительно непосредственно не имеют дело с Вашим классом, не будут загромождать его.
я чувствую, что дополнительные методы делают Ваш код более четким и более соответственно организованным.
В моем последнем проекте я использовал дополнительный метод для присоединения, Проверяют () методы к бизнес-объектам. Я выровнял по ширине это, потому что бизнес-объекты, где сериализуемая передача данных возражает и будет использоваться в различных доменах в качестве них, где общие объекты электронной коммерции, такие как продукт, клиент, продавец и т.д. Хорошо в различных доменах бизнес-правила могут отличаться также, таким образом, я инкапсулировал свою последнюю связанную логику проверки в Проверить методе, присоединенном к базовому классу моих объектов передачи данных. Надежда это имеет смысл :)
Один случай, где дополнительные методы были довольно полезны, был в клиентском приложении, которое использует веб-сервисы ASMX. Из-за сериализации, типы возврата веб-методов не содержат методов (только общественные собственности этих типов доступны на клиенте).
Дополнительные методы позволили использованию добавлять функциональность (на клиентском) к типам, возвращенным веб-методами, не имея необходимость создавать еще одну объектную модель или многочисленные классы обертки на клиентском.
У меня есть только одно слово для сообщения об этом: ПРИГОДНОСТЬ ДЛЯ ОБСЛУЖИВАНИЯ это - ключ для дополнительного использования методов
Это позволяет C# лучше поддерживать динамические языки, LINQ и дюжину других вещей. Выезд статья .
Scott GuthrieЯ использую их для многократного использования моих классов объектной модели. У меня есть набор классов, которые представляют объекты, которые я имею в базе данных. Эти классы используются в стороне клиента только для отображения объектов, таким образом, основное использование получает доступ к свойствам.
public class Stock {
public Code { get; private set; }
public Name { get; private set; }
}
Из-за того шаблона использования я не хочу иметь методы бизнес-логики в этих классах, таким образом, я делаю каждую бизнес-логику, чтобы быть дополнительным методом.
public static class StockExtender {
public static List <Quote> GetQuotesByDate(this Stock s, DateTime date)
{...}
}
Этот путь я могу использовать те же классы для обработки бизнес-логики и для пользовательского интерфейса, отображающегося, не перегружая сторону клиента с ненужным кодом.
Одна интересная вещь об этом решении случается так, что мои классы объектной модели являются динамическим сгенерированным использованием Моно. Cecil, таким образом, было бы очень трудно добавить методы бизнес-логики, даже если бы я хотел. У меня есть компилятор, который читает файлы определения XML, и генерируйте эти классы тупиков, представляющие некоторый объект, который я имею в базе данных. Единственный подход в этом случае должен расширить их.
Дополнительные методы являются действительно объединением.NET , "Представляют Внешний Метод" , осуществляют рефакторинг из Книги Martin Fowler (вниз к сигнатуре метода). Они идут в основном с теми же преимуществами и ловушками. В разделе по этому осуществляют рефакторинг, он говорит, что они - обходное решение для того, когда Вы не можете изменить класс, который должен действительно владеть методом.
Я главным образом рассматриваю дополнительные методы как подтверждение, что, возможно, они не должны были запрещать бесплатные функции.
В сообществе C++, это часто считают хорошей практикой ООП для предпочтения бесплатных не являющихся членом функций по участникам, потому что эти функции не повреждают инкапсуляцию путем получения доступа к членам парламента, не занимающим официального поста, в которых они не нуждаются. Дополнительные методы, кажется, окольный способ достигнуть того же самого. Таким образом, более чистый синтаксис для статических функций, которые не имеют доступа к членам парламента, не занимающим официального поста.
Дополнительные методы являются не чем иным как синтаксическим сахаром, но я не вижу вреда в использовании их.
Его истинное, что можно добавить (дополнительный) метод непосредственно в класс. Но не все классы записаны Вами. Классы от оперативной библиотеки или сторонних библиотек часто закрываются, и было бы невозможно получить синтетический сахар без дополнительных методов. Но помните, дополнительные методы точно так же, как (статические) автономные методы в, например, C++
Существует "куча" больших ответов выше о том, что дополнительные методы позволяют Вам сделать.
Мой короткий ответ - они почти избавляют от необходимости фабрики.
я просто укажу, что они не новое понятие, и одна из самых больших проверок их - то, что они - уничтожающая функция в Objective C ( категории ). Они добавляют такую гибкость к основанной на платформе разработке, что NeXT имел NSA и Уолл-стрит финансовые разработчики моделей как крупные пользователи.
REALbasic также реализует их, поскольку расширяет методы , и они имели подобное применение, там упрощающее разработку.
Дополнительные методы могут также помочь сохранить Ваши классы и зависимости от класса чистыми. Например, Вам, возможно, понадобится Панель () метод для класса Foo везде, Foo используется. Однако можно хотеть.ToXml () метод в другом блоке и только для того блока. В этом случае можно добавить необходимый System.Xml и/или Систему. Xml. Зависимости Linq в том блоке а не в исходном блоке.
Преимущества: зависимости в Вашем блоке класса определения уменьшаются только до минимальных потребностей, и другим блокам потребления будут препятствовать использовать ToXml () метод. См. эта презентация PDC для дальнейшей ссылки.
Мой персональный аргумент в пользу Дополнительных методов, они соответствуют очень хорошо дизайну ООП: рассмотрите простой метод
bool empty = String.IsNullOrEmpty (myString)
по сравнению с
bool empty = myString.IsNullOrEmpty ();
Одной из больших причин использования дополнительных методов является LINQ. Без дополнительных методов многое из того, что можно сделать в LINQ, было бы очень твердо. Где (), Содержит (), Избранные дополнительные методы означает, что намного больше функциональности добавляется к существующим типам, не изменяя их структуру.
Быстрые Интерфейсы и Чувствительность Контекста , как продемонстрировано Greg Young на CodeBetter
Еще два преимущества дополнительных методов, с которыми я столкнулся:
Часть лучшего использования, которое я имел для дополнительных методов, является способностью к:
sealed
. , Берут, например, IEnumerable<T>
. В то время как это богато дополнительными методами, я нашел это раздражающим, что это не реализовало универсальный метод ForEach. Так, я сделал свое собственное:
public void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach ( var o in enumerable )
{
action(o);
}
}
Вуаля, весь мой IEnumerable<T>
объекты независимо от реализации типа, и записал ли я это или кто-то еще действительно теперь имел ForEach
метод путем добавления соответствующего оператора "использования" в моем коде.
Не забывайте оснащать! Когда Вы добавляете дополнительный метод M на типе Foo, Вы получаете 'M' в списке intellisense Foo (предполагающий, что дополнительный класс в объеме). Это делает 'M' намного легче найти, чем MyClass. M (Foo...).
В конце дня, это - просто синтаксический сахар для в-другом-месте-статических-методов, но как покупка дома: 'местоположение, местоположение, местоположение!' Если это зависнет на типе, то люди найдут его!
только преимуществом дополнительных методов является удобочитаемость кода. Вот именно.
Дополнительные методы позволяют Вам делать это:
foo.bar();
вместо этого:
Util.bar(foo);
Теперь существует много вещей в C#, которые похожи на это. Другими словами, существует много функций в C#, которые кажутся тривиальными и не обладают большим преимуществом в и себя. Однако, после того как Вы начинаете сочетать эти функции вместе, Вы начинаете видеть что-то просто немного большее, чем сумма его частей. Преимущества LINQ значительно от дополнительных методов как запросы LINQ были бы почти нечитабельны без них. LINQ был бы возможен без дополнительных методов, но не практичный.
Дополнительные методы много похожи на частичные классы C#. Собой они не очень полезны и кажутся тривиальными. Но когда Вы начинаете работать с классом, которому нужен сгенерированный код, частичные классы начинают иметь намного больше смысла.
Это позволяет Вашему редактору/IDE, действительно автоматически заполняют умное предложение.
Я люблю их за создание html. Часто есть разделы, которые используются повторно или генерируются рекурсивно, когда функция полезна, но в противном случае нарушает поток программы.
HTML_Out.Append("<ul>");
foreach (var i in items)
if (i.Description != "")
{
HTML_Out.Append("<li>")
.AppendAnchor(new string[]{ urlRoot, i.Description_Norm }, i.Description)
.Append("<div>")
.AppendImage(iconDir, i.Icon, i.Description)
.Append(i.Categories.ToHTML(i.Description_Norm, urlRoot)).Append("</div></li>");
}
return HTML_Out.Append("</ul>").ToString();
Также существуют ситуации, когда объекту требуется настраиваемая логика для подготовки для вывода HTML - методы расширения позволяют вы добавляете эту функциональность без смешивания представления и логики внутри класса.
Я нашел методы расширения полезны для сопоставления вложенных общих аргументов.
Это звучит немного странно - но у нас есть общий класс MyGenericClass
, и мы знаем, что само по себе TList является общим (например, List
), Я не думаю, что есть способ выкопать, что вложенный «T» из списка без методов расширения, ни методы статического помощника. Если у нас есть только методы статического помощника только в нашем распоряжении, он (а) уродливый, а (b) заставит нас перемещать функциональность, принадлежащие в классе к внешнему расположению.
E.G. Чтобы извлечь типы в кортеж и преобразовывать их в подпись метода, мы можем использовать методы расширения:
public class Tuple { }
public class Tuple<T0> : Tuple { }
public class Tuple<T0, T1> : Tuple<T0> { }
public class Caller<TTuple> where TTuple : Tuple { /* ... */ }
public static class CallerExtensions
{
public static void Call<T0>(this Caller<Tuple<T0>> caller, T0 p0) { /* ... */ }
public static void Call<T0, T1>(this Caller<Tuple<T0, T1>> caller, T0 p0, T1 p1) { /* ... */ }
}
new Caller<Tuple<int>>().Call(10);
new Caller<Tuple<string, int>>().Call("Hello", 10);
, которые сказали, что я не уверен, что должна быть разделительной линие - когда должен быть метод расширения, а когда должен Это статический помощник методом? Любые мысли?
Существует много ответов о преимуществах методов расширений; Как насчет одного обращения к недостаткам ?
Самым большим недостатком является то, что нет ошибки компилятора или предупреждения, если у вас есть обычный метод и метод расширения с той же подписью в одном контексте.
Предположим, вы создаете метод расширения, применяемый к определенному классу. Затем позже кто-то создает метод с идентичной подписью на самом классе.
Ваш код будет компитен, и вы даже не получаете ошибку выполнения. Но вы больше не работаете один и тот же код, что и раньше.