2009-04-21 10 views
11

私はJosh Smith's CommandSink codeを使って作業していますが、明らかにC#の "as"キーワードについて何か分かりません。シンプルキャスティングよりもC#の "as"キーワードの方が多いですか?

彼はラインを書いた理由を私は理解していない:それはケースになることはないので

IsValid = depObj != null; 

_feがnullと_fce次のようになります。彼は唯一の書き込みに必要なので、

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

を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; 
    } 
    ... 

ANSWER:

答えはマルクが 『と彼のコメント」の全体のポイントがある』で言っている - それはが例外をスローしません - それは単にヌルを報告します。 "

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; } 
    } 

} 

答えて

26

asオペランドに互換性がある場合は、あなたが要求した型のオブジェクトを返します。ここ

とは証拠です。そうでなければ、nullを返します。 asを使用していて、キャストに失敗する可能性がある場合は、参照が有効であることを確認する必要があります。例えば

depObjはタイプStringであったならば、それはnullではないでしょうが、また、要求された種類のいずれかに変換すると、これらの変数の両方がnullになることはできないであろう。

+0

ああ、毎日新しいことを学びます。私は似たようなことを提案しようとしていましたが、キャストできないと例外をスローすることを前提としていました。 –

+7

@Gordon - それは "as"の全体のポイントです - 例外はスローされません。ヌルと報告する。 –

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

IsValid = depObj != null; 

depObjがタイプのFrameworkElementやFrameworkContentElementのではないですが、最初はfalseを返します間に、第2のテストは、trueを返しますnullでない場合ので、同じテストではありません。

1

DependencyObject depObjが実際にFrameworkOtherTypeOfElement

た場合、depObjがnull

ではないだろうが試みられasキャストの両方がnullに評価し、_fe & _fceでしょうが両方ともNULLになり

asされます同等にする

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

depObjFrameworkElementでもFrameworkContentElementでもない場合はどうなりますか?私は完全なシナリオ(すなわち、どのようなタイプになる可能性があるか)はわかりませんが、これは合理的な防御戦略のようです。同じように "それがある場合、キャストは、"、および同等に

5

は:

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

それはis + castよりも効率的、しかしです。

depObjは、interface、none、またはその両方を実装できます。

2

最初に、asキーワードにはisの小切手が含まれています。

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

BのタイプAから変換演算子が定義されている場合でも、キャストのようなタイプが行う変換しません

a = o as A; 

第二に、asと同じです。

+0

まあ、それは間違いなく繰り返されるでしょう...スタックオーバーフロー! – murki

+0

haha​​、true。それはキャストを意味していたが、良いC#プログラミングの習慣はキャストを "as"演算子に書き直した:D –

関連する問題