C # Extensions - это дополнительный «инструмент», предоставляемый .Net, чтобы помочь вам написать свой код немного лучше. Еще одним преимуществом является то, что они обрабатывают ноль. Хотя они кажутся очень удобными, я пытаюсь использовать их только в определенных случаях, которые действительно приведут в порядок мой код, потому что они не являются стандартными методами кодирования, и они немного отличаются от других классов, поскольку они должны быть в статических классах и статичны сами.
Допустим, их реализация немного неопрятна, но их использование сделано более аккуратным .
Также важно упомянуть, что они существуют только в C # и VB.Net (Java не имеет расширений). Другим важным фактом является то, что расширения не имеют приоритета над стандартными методами, а это означает, что если метод реализован в классе с тем же именем, что и метод расширения в том же классе, то первым будет вызван метод, а не метод. метод расширения.
Ниже приведены три случая, в которых я часто их использую, почему я их использую и альтернативные решения, которые решат ту же проблему:
1. Чтобы реализовать конкретные методы для универсальных классов:
У меня есть универсальный тип, скажем, коллекция List<T>
. Я хочу сделать метод, который применяется только к определенному виду списка. Скажем, метод, который создает объединение из списка строк, используя разделитель
("A", "B", "C", " sep " --> "A sep B sep C"
):
public static string union(this List<string> stringList, String seperator)
{
String unionString = "";
foreach (string stringItem in stringList) {
unionString += seperator + stringItem; }
if (unionString != "") {
unionString = unionString.Substring(seperator.Length); }
return unionString;
}
Если бы я не хотел использовать расширение, мне нужно было бы создать новый класс "StringCollection : List<string>
" и реализовать там мой метод. Это в основном не проблема, и на самом деле это лучше в большинстве случаев, но не во всех случаях. Например, если во многих случаях вы получаете все свои данные в списках строк, вам не нужно конвертировать эти списки в StringCollections
каждый раз, когда вы хотите использовать объединение, но вместо этого использовать расширение.
2. Для реализации методов, которые должны обрабатывать нуль:
Мне нужен метод для преобразования объекта в строку без исключения в случае, если объект является нулевым
public static String toStringNullAllowed(this Object inputObject)
{
if (inputObject == null) { return null; }
return inputObject.ToString();
}
Если бы я не хотел использовать расширение, мне пришлось бы создать класс (возможно, статический), например StringConverter
, который будет выполнять ту же работу, с большим количеством слов, чем простой myObject.toStringNullAllowed();
3. Чтобы расширить типы значений или запечатанные классы:
Типы значений, такие как int, float, string и т. Д., А также запечатанные классы (классы, которые не могут быть унаследованы) не могут быть расширены посредством наследования. Ниже вы можете увидеть пример расширения целых чисел, которое можно преобразовать в x-разрядные строки (например, integer 34, digits 5 --> "00034"
):
public static String toXDigit(this int inputInteger, int x)
{
String xDigitNumber = inputInteger.ToString();
while (xDigitNumber.Length < x) { xDigitNumber = "0" + xDigitNumber; }
return xDigitNumber;
}
Опять же, альтернативным решением будет статический класс (например, набор инструментов), скажем, "Math".
- В этом случае вы бы написали:
Math.toXDigit(a, x);
- При использовании метода расширения:
a.toXDigit(x);
Метод расширения выглядит лучше и понятнее, как говорящий по-английски
В заключение, я предполагаю, что недостатком расширений является то, что их реализация отделена от стандартных классов и выглядит немного странной или сложной для программистов, которые не привыкли к ним, в то время как их преимущество заключается в том, что они предлагают больше понятное, аккуратное и инкапсулированное использование языка.