Использует метод расширения для создания плохой идеи? - программирование
Подтвердить что ты не робот

Использует метод расширения для создания плохой идеи?

Недавно я начал работать в WPF, и я заметил, что вам нужно сделать много кастинга (особенно с событиями). Это эстетическая проблема, но мне было интересно, насколько это было бы плохо, если бы я использовал метод расширения для отливки вместо обычного каста.

public static T Cast<T>(this object obj)
{
    return (T)obj;
}

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

Console.WriteLine(((DataGridCell)e.OriginalSource).ActualHeight);

в

Console.WriteLine(e.OriginalSource.Cast<DataGridCell>().ActualHeight);

Есть ли какие-то явные недостатки, которые я могу игнорировать? Как отвращение будет людям, когда они столкнутся с этим в коде?:)

4b9b3361

Ответ 1

Это похоже на намерение Enumerable.Cast, поэтому я не обязательно буду говорить, что людям будет отвращаться.

Есть ли явные недостатки, которые я могу игнорировать?

Основной недостаток заключается в том, что это будет метод расширения, доступный для каждой отдельной переменной вашего кода, поскольку вы расширяете System.Object. По этой причине я обычно избегаю методов расширения на Object, так как он "загрязняет" intellisense.

При этом есть и другие недостатки:

Если вы использовали это в существующем IEnumerable, вы получили бы столкновение имен с Enumerable.Cast<T>. Файл, содержащий ваше пространство имен, но отсутствующий using System.Linq, может быть легко неправильно понят другими разработчиками, поскольку это будет иметь совсем другое значение для ожидаемого метода расширения <<26 > .

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

int i = 42; 
float f = i.Cast<float>();

Это может быть неожиданно, так как float f = (float)i; является совершенно законным. Для получения дополнительной информации см. Сообщение Эрика Липперта в Представление и идентификация. Если вы это сделаете, я определенно рекомендую добавить к вашему оператору ограничение .

Я лично использовал бы круглые скобки. Это общая, поддерживаемая языками функция, и она должна быть понятна всем разработчикам С#. Кастинг имеет преимущества быть короткими, понятными и свободными от побочных эффектов (с точки зрения intellisense и т.д.).

Другой вариант - сделать это обычным статическим методом, который позволит вам написать:

Console.WriteLine(Utilities.Cast<DataGridCell>(e.OriginalSource).ActualHeight);

Это устраняет недостаток "загрязняющего" intellisense и делает очевидным, что его метод, который вы написали, но увеличивает объем ввода, который требуется использовать. Он также не делает ничего, чтобы предотвратить проблему с боксом и распаковкой/броском.

Ответ 2

Основной недостаток заключается в том, что литье хорошо известно для каждого разработчика С#, в то время как ваш метод Cast<T> - это еще одно не изобретенное здесь колесо. Следующим шагом, как правило, является набор расширений типа IsTrue, IsFalse, IsNull и т.д.

Это мусор синтаксиса.