Есть ли веские причины ПРОТИВ использования ключевого слова C # «как»? - PullRequest
7 голосов
/ 20 февраля 2009

Я считаю, что с помощью следующего:

TreeViewItem i = sender as TreeViewItem;
if(i != null){ ... }

легче написать и понять, чем:

if(sender.GetType() == typeof(TreeViewItem)){
    TreeViewItem i = (TreeViewItem)sender;
    ...
}

Есть ли веские причины не использовать первую конструкцию?

Ответы [ 9 ]

12 голосов
/ 20 февраля 2009

Я предпочитаю приведение к as в большинстве случаев, потому что обычно, если тип объекта неправильный, это указывает на ошибку. Ошибки должны вызывать исключения IMO - и InvalidCastException точно в строке, которая выполняет приведение, намного яснее, чем NullReferenceException намного позже в коде.

as следует использовать, когда допустимо и разрешено передавать ссылку на объект того типа, который вам не нужен. Такая ситуация возникает, но не так часто, как в моем опыте.

Сравнение типов с использованием GetType(), однако, очень редко является правильным решением - оно подходит, только если вы хотите проверить наличие точного типа, а не совместимого типа.

Я написал значительно более длинный ответ о дискуссии "Cast vs as" в другом месте.

7 голосов
/ 20 февраля 2009

Совсем нет - это дает вам возможность убедиться, что преобразование (приведение) было сделано в порядке. Если вы делаете

TreeViewItem i = (TreeViewItem) sender;

вы можете получить исключение в случае неудачного приведения.

6 голосов
/ 20 февраля 2009

Вообще говоря, эти два фрагмента не эквивалентны. TreeViewItem i = sender as TreeViewItem даст правильный результат, даже если sender будет пра-пра-пра-дитя TreeViewItem, тогда как sender.GetType() == typeof(TreeViewItem) будет true только , когда sender точно TreeViewItem и ни один из его возможных подклассов.

4 голосов
/ 20 февраля 2009

Ваш пример лучше записать как:

if (sender is TreeViewItem) {
    TreeViewItem i = (TreeViewItem)sender;
    ...
}

Именно эта двойная проверка помогает избежать оператора as. Поэтому для вашего приведенного примера я бы сказал, что это определенно хорошее решение.

Однако бывают ситуации, когда вы действительно хотите хотеть сыграть. Если вы ожидаете TreeViewItem и больше ничего не хотите, приведение гарантирует, что вы получите InvalidCastException, если вам дадут что-то еще.

Как и в большинстве ситуаций, здесь нет общего правила: используйте правильный инструмент для правильной работы .

4 голосов
/ 20 февраля 2009

"как": хороший материал. используйте это все время.

, если вы действительно хотите альтернативу сравнению типов вручную, попробуйте:

  if(person is Employee) { }

еще лучше читает.

2 голосов
/ 20 февраля 2009

Если вам нужен простой (не обнуляемый) тип значения, очевидно, это не сработает, например:

int test = sender as int;

недействительно, однако:

int? test = sender as int?;

разрешено.

1 голос
/ 20 февраля 2009

Если получение неправильного типа было бы ошибкой, тогда вы должны использовать приведение. Причина этого в том, что проблема действительно существует, и вы должны о ней знать.

Если возможно, что значение будет нулевым, и это не является ошибкой в ​​системе, когда это происходит, используйте «as». Причина в том, что вы должны использовать «как» в любое время, когда возврат нуля является приемлемым.

Имейте в виду, что вы не можете использовать «как» для преобразования в типы значений, поскольку для них недопустимое значение NULL. Если у вас есть тип значения и вы хотите использовать «как», вам нужно будет использовать тип значения NULL.

Когда использовать "как" по сравнению с кастингом

1 голос
/ 20 февраля 2009

Нет, я использую это совсем немного. Это позволяет вам избегать InvalidCastException s в чистом виде.

Например:

TreeViewItem tvItem = sender as TreeViewItem;

if (tvItem != null) return;

// Do stuff

вместо:

try
{
    TreeViewItem tvItem = (TreeViewItem)sender;
    // Do stuff.
}
catch (InvalidCastException ex)
{
    // Didn't work, do something about it
    return; // ... or not...
}
1 голос
/ 20 февраля 2009

«как» быстрее, но следует помнить следующее:

  • «as» возвращает ноль вместо выдачи исключения, если это проблема

  • он не будет выполнять пользовательские преобразования iirc

  • не работает для справки-> значение

Редактировать: «как» определенно быстрее (http://www.codeproject.com/KB/cs/csharpcasts.aspx)

Edit2: так что в основном скорость против решения о безопасности

...