Есть ли больше для ключевого слова С# "как", чем простое литье?

Я работаю через код Josh Smith CommandSink, очевидно, ничего не понимаю о ключевом слове "as" в С#.

Я не понимаю, почему он написал строку:

IsValid = _fe != null || _fce != null;

так как ему нужно было только написать:

IsValid = depObj != null;

Так как это никогда не будет, _fe будет null и _fce не null, или наоборот, не так ли? Или мне не хватает чего-то о том, как "как" отличает переменные?

class CommonElement
{
    readonly FrameworkElement _fe;
    readonly FrameworkContentElement _fce;

    public readonly bool IsValid;

    public CommonElement(DependencyObject depObj)
    {
        _fe = depObj as FrameworkElement;
        _fce = depObj as FrameworkContentElement;

        IsValid = _fe != null || _fce != null;
    }
    ...

Ответ:

Ответ - это то, что Марк сказал в своем комментарии ", что является всей точкой" как "- он не будет генерировать исключение - он просто сообщает null."

и здесь доказательство:

using System;

namespace TestAs234
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer();
            Employee employee = new Employee();

            Person.Test(customer);
            Person.Test(employee);
            Console.ReadLine();
        }

    }

    class Person
    {
        public static void Test(object obj)
        {
            Person person = obj as Customer;

            if (person == null)
            {
                Console.WriteLine("person is null");
            }
            else
            {
                Console.WriteLine("person is of type {0}", obj.GetType());
            }
        }
    }

    class Customer : Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

    class Employee : Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

}

Ответ 1

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

Например, если depObj имеет тип String, он не будет null, но он также не сможет быть преобразован ни в один из запрошенных типов, и обе эти переменные станут null.

Ответ 2

как и "cast, if it is", и эквивалентно:

(X is TYPE) ? (TYPE) X : null

он, однако, более эффективен, чем is + cast.

depObj может реализовать либо интерфейс, ни один, либо оба.

Ответ 3

IsValid = _fe != null || _fce != null;

и

IsValid = depObj != null;

- не те же тесты, потому что если depObj не относится к типу FrameworkElement или FrameworkContentElement, но не является нулевым, второй тест вернет true, а первый вернет false.

Ответ 4

Что делать, если depObj не является FrameworkElement или FrameworkContentElement? Я не знаю полного сценария (т.е. Того, какими могут быть типы), но это кажется разумной защитной стратегией.

Ответ 5

Во-первых, ключевое слово as включает проверку is.

if( o is A)
   a = (A) o;

совпадает с

a = o as A;

Во-вторых, as не преобразует тип, как приведение, даже если задан оператор преобразования из типа A в B.

Ответ 6

Что, если DependencyObject depObj на самом деле был FrameworkOtherTypeOfElement

Тогда depObj не будет null

но попытка as Casts будет равна нулю, а _fe и _fce будут равны нулю

as эквивалентно выполнению

if(I Can Cast This Object)
   //Then cast it
else
   //Return null