Методы расширения и класс статической полезности
Я ищу некоторые плюсы и минусы для использования методов расширения поверх статических классов утилиты в приложении С#.
Например, плюсом в столбце методов расширения является удобство вызова по имени класса, а не нечто вроде "StringUtils". Но конфликт был бы в том, что он может размыть линии между тем, что находится в рамках, а что нет.
Ответы
Ответ 1
Я бы сказал, что pro - это то, что он размывает линии между тем, что находится в рамках, а что нет: вы можете использовать свой собственный код так же естественно, как и код рамки, работающий на типах фреймов.
Методы расширения не должны использоваться произвольно, конечно - это не похоже на то, что все статические методы должны стать методами расширения.
Я пытаюсь думать о нем, как метод логически управляет "on" его первым параметром. Будет ли это иметь смысл как метод экземпляра, если бы вы могли включить его в качестве метода экземпляра?
A "con", о котором вы не можете знать: если позднее расширенный тип добавляет метод экземпляра того же имени, который применим к тем же параметрам, ваш код вызова будет прозрачно запускать этот метод экземпляра в следующий раз, когда вы перекомпилируете, Например, Stream
получил CopyTo
в .NET 4... Ранее я написал метод расширения CopyTo
, который затем не будет называться. Там нет предупреждения, что это происходит, поэтому вы должны быть настороже.
Одно предостережение: методы расширения не были созданы достаточно долго, чтобы действительно установить лучшие практики. Вы должны тщательно взвешивать все мнения (даже, возможно, особенно - мои собственные).
Ответ 2
В конце дня оба подхода используют статические методы. Единственная разница между
string foo = "bob";
StringUtils.DoSomething(foo);
и
string foo = "bob";
foo.DoSomething();
- синтаксический сахар. Это сводится к личным предпочтениям и стандартам кодирования. Иногда имя метода может быть достаточно дескриптивным, чтобы не гарантировать вид статического имени класса. В других случаях имеет смысл включать имя класса.
Наконец, методы расширения можно также вызвать как статические методы!
string foo = "bob";
StringExtensions.DoSomething(foo);
В приведенном выше примере используется тот же код, что и во втором примере, но вызывается по-разному. Имея в виду этот последний лакомый кусочек, вы действительно можете создавать статические классы утилиты в качестве методов расширения, а затем вызывать их, как хотите.
Ответ 3
Мне лично нравятся readabilty и chain calls (неявно обеспечивает читаемость), предоставляемые методами расширения.
1) Readability:
bool empty = String.IsNullOrEmpty (myString)
//in comparison to
bool empty = myString.IsNullOrEmpty ();
2) Chain calls:
var query = Enumerable.Range(0, 10)
.Where(x => x % 2 == 0)
.Reverse();
//instead of
var query = Enumerable.Reverse(Enumerable.Where(Enumerable.Range(0, 10), x => x % 2 == 0));
Con - ваш метод расширения может быть переопределен членом-членом, если вы случайно это сделаете. Лично мне это не нравится. По крайней мере, компилятор должен был кричать, если это происходит в той же сборке.