оценка затрат/преимуществ использования методов расширения в C# => 3.0 [закрыто]

в каких обстоятельствах (сценарии использования) вы бы предпочли написать расширение, а не подкласс объекта ?

Я нахожу идею методов расширения "классной", и, очевидно, вы можете делать с ними" далекие " вещи, как во многих примерах, которые вы можете в блогах Mitsu Furota (MS)текст ссылки.

личный друг написал библиотеку Componax с открытым исходным кодомтекст ссылки, и там есть некоторые замечательные объекты; но он полностью командует своей небольшой ротой с полным контролем над кодом руководящие принципы, и каждая строка кода "проходит через его руки."

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

глядя на рекомендации MS в текст ссылки, вы найти :

В общем, вы, вероятно, будет вызов методов расширения far more часто, чем реализовать свой собственный. ... В общем, мы рекомендуем что ты реализуйте методы расширения экономно и только когда придется. Всякий раз возможно, клиентский код, который должен распространяться существующий тип должен создание нового типа, производного от существующий тип. За дополнительной информацией, см. раздел наследование (программирование на C# Руководство.) ... Когда компилятор встречает вызов метода, это сначала ищет совпадение в типе метод экземпляра. Если нет матча найденный, он будет искать любой методы расширения, определенные для этот введите и привяжите к первому метод расширения, который он находит.

и в MS это текст ссылки :

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

факторы, которые кажутся мне очевидными, включают:

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

  2. зная, что мы можем скомпилировать их в отдельную dll, и добавить скомпилированную dll, и ссылаться на нее, а затем использовать расширения : "круто", но делает ли это " баланс" стоимость, присущая компилятору, сначала должна проверить, определены ли методы экземпляра, как описано выше. Или стоимость, в случае "столкновения имен", использования статических методов вызова, чтобы убедиться, что ваше расширение вызывается, а не определение экземпляра ?

как частое использование расширений повлияет на производительность во время выполнения или использование памяти : я понятия не имею.

Итак, я был бы признателен за ваши мысли, или зная о том, как/когда вы делаете, или нет do, используйте расширения, по сравнению с подклассами.

спасибо, Билл

4 ответов


мое самое большое использование для них-расширить закрытые сторонние API.

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

ранее, когда это нужно было сделать, и я не удалось наследовать объект API, потому что он был запечатан или что-то еще, я бы полагался на шаблон адаптер чтобы сделать мои собственные классы, которые завернули свои объекты. Это функциональное, но довольно неэлегантное решение. Методы расширения даст вам прекрасный способ добавить больше функциональности к тому, что вы не контролируете.

многие другие народы' наибольшее использование для них является LINQ!

LINQ не было бы возможно без методы расширения, предоставляемые IEnumerable.

причина, почему люди любят их, потому что они делают код более читабельным.

Я заметил, что другое основное использование методов расширения (включая меня) - сделать код более читаемым и сделать его похожим на код, чтобы сделать что-то принадлежит там, где он должен. Он также избавляется от страшного класса статического Бога "Util", который я видел много раз. Что выглядит лучше... Util.DecimalToFraction(decimal value); или value.ToFraction();? Если вы похожи на меня, то последнее.

наконец, есть те, кто считает "статический метод" как зло!

многие хорошие программисты скажут вам, что вы должны стараться избегать статических методов, особенно тех, кто использует обширный модульного тестирования. Статические методы трудно проверить в некоторых случаях, но они не зло при правильном использовании. В то время как методы расширения ARE статический... они не смотри и не веди себя так. Это позволяет получить эти статические методы из ваших классов и на объекты, к которым они действительно должны быть прикреплены.

по поводу производительности..

методы расширения ничем не отличаются от вызова статического метода, передавая объект расширения в качестве параметра... потому что это то, во что его превращает компилятор. Самое замечательное в этом то, что ваш код выглядит чистым, он делает то, что вы хотите, и компилятор обрабатывает грязная работа для тебя.


Я использую методы расширения как способ улучшить функциональность для классов без увеличения сложности класса. Вы можете сохранить свои классы простыми, а затем добавить свою повторяющуюся работу позже в качестве расширения.

на Min() и Max() методы расширения являются хорошими примерами этого. Вы можете так же легко объявить частный метод, который будет вычислять их, но метод расширения обеспечивает лучшую читаемость, делает функциональность доступной для весь ваш проект, и не требовал делать массив более сложным из объекта.


принятие подхода подклассов против методов расширения требует, чтобы пара вещей была истинной

  1. тип должен быть extendable (не-загерметизированный)
  2. все места, где создается тип, должны поддерживать фабричный шаблон или другой код просто создаст базовый тип.

добавление метода расширения не требует ничего, кроме использования компилятора C# 3.0+.

но самое главное, иерархия наследования должна представляйте отношения is-a. Я не чувствую, что добавление 1 или 2 новых методов / поведения в класс действительно выражает этот тип отношений. Вместо этого он усиливает существующее поведение. Класс-оболочка или метод расширения гораздо лучше подходят для сценария.


в некоторых случаях вы не можете использовать подкласс: строку, например, запечатан. Однако вы можете добавлять методы расширения.