Использование оператора as для приведения, даже после использования оператора для проверки типа класса в C #? - PullRequest
3 голосов
/ 21 июля 2011

Я понимаю, что использование оператора as для приведения объекта поверх явного приведения обычно более желательно из-за того, что в случае сбоя приведения ссылочная переменная обнуляется, а не вызывает исключение.

Однако, допустим, я проверил, чтобы увидеть тип класса объекта, который находится внутри списка, перед использованием оператора as, например,

DrawableGameComponent drawComponent;
foreach (component in Components)
{
     if (component is DrawableGameComponent)
     {
          drawComponent = component as DrawableGameComponent;

         // do something with drawComponent
     }
}

теряет ли использование оператора as свои преимущества, сначала проверяя оператор is? Таким образом, выполнение следующего приведения так же хорошо, потому что мы сначала проверяем тип класса, используя is, прежде чем пытаться выполнить приведение?

if (component is DrawableGameComponent)
{
     ((DrawableGameComponent)componet).Visible = true;
}

Мне просто интересно, есть ли какая-то основная деталь, которую я пропускаю, или это действительно сводится к вопросу вкуса, какой шаблон использовать. Создает ли последний шаблон мусор через явное приведение?

Заранее спасибо!

Ответы [ 5 ]

11 голосов
/ 21 июля 2011

лучше (сохраняет один «бросок» - сравните сгенерированный IL):

DrawableGameComponent drawComponent;
foreach (component in Components)
{
     drawComponent = component as DrawableGameComponent;
     if (drawComponent != null)
     {


         // do something with drawComponent
     }
}
5 голосов
/ 21 июля 2011

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

Я очень предпочитаю использовать as и тестирование на ноль, а также очисткуВаше объявление для еще меньшего количества строк:

foreach (component in Components)
{
     var drawComponent = component as DrawableGameComponent;
     if (drawComponent != null)
     {
          // do something with drawComponent
     }
}
1 голос
/ 21 июля 2011

Я бы использовал

DrawableGameComponent drawComponent;
foreach (component in Components)
{
    drawComponent = component as DrawableGameComponent;
    if (drawComponent != null)
    {
        // do something with drawComponent
    }
 }

FXCop , чтобы помочь подобрать места в вашем коде, которые могут извлечь выгоду из небольших оптимизаций, подобных этой

0 голосов
/ 21 июля 2011

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

public class A
{   
}

public class B : A
{
    public bool Visible { get; set; }
}

public class C : A
{
}

void Main()
{
    var data = new List<A> { new A(), new B(), new C(), new B() };

    data.OfType<B>().ToList().ForEach(x => x.Visible = true);
}
0 голосов
/ 21 июля 2011

Комбинируя is и as, вы фактически делаете проверку типов дважды.Просто использование as в этом контексте (как показывают другие ответы) дает вам то, что вы хотите, и приводит к более читаемому коду IMO.

...