Есть ли больше для ключевого слова С# "как", чем простое литье?
Я работаю через код 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