C#“as”关键字还有比简单投射更多的东西吗?
我正在研究Josh Smith的CommandSink代码,显然对C#中的“as”关键字一无所知。
我不明白他为什么写这条线:
IsValid = _fe != null || _fce != null;
因为他只需要写:
IsValid = depObj != null;
既然永远不会出现这种情况,_fe将为null而_fce不为null,反之亦然,对吧? 或者我错过了关于“as”如何投射变量的内容?
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; } ...
回答:
答案是马克在他的评论中所说的“ 这是”作为“的全部观点 – 它不会抛出exception – 它只是报告无效 。”
这是证据:
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; } } }
如果操作数兼容as
将返回您请求的类型的对象。 如果不是,则返回null
。 如果您使用as
并且转换可能会失败,则需要检查以确保引用有效。
例如,如果depObj的类型为String
,则它不会为null
,但它也无法转换为任何一个请求的类型,并且这两个变量都将变为null
。
就像“施放,如果是”一样,相当于:
(X is TYPE) ? (TYPE) X : null
然而,它比+ + cast
效率更高。
depObj可以实现interface,none或两者。
IsValid = _fe != null || _fce != null;
和
IsValid = depObj != null;
不是相同的测试,因为如果depObj不是FrameworkElement类型,也不是FrameworkContentElement类型但不是null,则第二个测试将返回true,而第一个测试将返回false。
如果depObj
既不是FrameworkElement
又不是FrameworkContentElement
怎么办? 我不知道完整的场景(即类型可能是什么),但这似乎是一个合理的防守策略。
首先, as
关键字包括a check。
if( o is A) a = (A) o;
是相同的
a = o as A;
其次,即使定义了从类型A
到B
的转换运算符,也不像转换那样转换类型。
如果DependencyObject depObj
实际上是FrameworkOtherTypeOfElement
该怎么办?
然后depObj
不会为null
但尝试Casts将评估为null, _fe
& _fce
都为null
等同于做
if(I Can Cast This Object) //Then cast it else //Return null