8

次のような明示的なキャストを使用すると、次のようになります。

(someType)someobject

someobjectそうでない場合は、無効なキャスト例外が発生する可能性がありますsomeType

同様に、次のようにキャストすると、次asのようになります。

myObject = someObject as someType

myObjectそうでないnull場合はレンダリングされます。someObjectsomeType

これらはどのように異なって評価され、その理由は?

4

2 に答える 2

7

John Skeet はC# faqを持っており、2 つの演算子の違いについて説明しています。「キャスト構文と as 演算子の使用の違いは何ですか?」の段落を参照してください。

見積もり :

as 演算子の使用は、次の 3 つの重要な点で C# のキャストとは異なります。

  1. 変換しようとしている変数が要求された型でない場合、またはその継承チェーンにない場合は、例外をスローする代わりに null を返します。
  2. 参照型に変換する参照型変数にのみ適用できます。
  3. as を使用すると、キャスト構文で実行される暗黙的または明示的な変換演算子などのユーザー定義の変換は実行されません。

実際、IL には、これら 2 つのキーワード (castclass 命令と isinst 命令) を処理する 2 つの完全に異なる操作が定義されています。この異なる動作を実現するために C# によって記述された「シンタックス シュガー」だけではありません。as 演算子は、Microsoft の CLR の v1.0 および v1.1 では、キャストと比較してわずかに高速であるように見えます (例外のためにキャストのパフォーマンスを大幅に低下させる無効なキャストがない場合でも)。

于 2011-02-21T08:01:25.370 に答える
0

何年も経ちました...しかし、数分前に、注目に値すると思われる実用的な例に出くわしました-2つの違いについて:

これをチェックしてください:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(GenericCaster<string>(12345));
        Console.WriteLine(GenericCaster<object>(new { a = 100, b = "string" }) ?? "null");
        Console.WriteLine(GenericCaster<double>(20.4));

        //prints:
        //12345
        //null
        //20.4

        Console.WriteLine(GenericCaster2<string>(12345));
        Console.WriteLine(GenericCaster2<object>(new { a = 100, b = "string" }) ?? "null");

        //will not compile -> 20.4 does not comply due to the type constraint "T : class"
        //Console.WriteLine(GenericCaster2<double>(20.4));

        /*
         * Bottom line: GenericCaster2 will not work with struct types. GenericCaster will.
         */
    }

    static T GenericCaster<T>(object value, T defaultValue = default(T))
    {
        T castedValue;
        try
        {
            castedValue = (T) Convert.ChangeType(value, typeof(T));
        }
        catch (Exception)
        {
            castedValue = defaultValue;
        }

        return castedValue;
    }

    static T GenericCaster2<T>(object value, T defaultValue = default(T)) where T : class
    {
        T castedValue;
        try
        {
            castedValue = Convert.ChangeType(value, typeof(T)) as T;
        }
        catch (Exception)
        {
            castedValue = defaultValue;
        }

        return castedValue;
    }
}

結論: GenericCaster2 は構造体型では機能しません。GenericCaster はそうします。

于 2015-07-20T15:00:45.777 に答える