null チェックがない場合でも、キャストの代わりに「as」を使用するのは意味がありますか? [closed] 質問する

null チェックがない場合でも、キャストの代わりに「as」を使用するのは意味がありますか? [closed] 質問する

開発ブログ、オンラインのコード例、そして(最近では)本でも、次のようなコードによく遭遇します。

var y = x as T;
y.SomeMethod();

さらに悪いことに:

(x as T).SomeMethod();

それは私には意味が分かりません。 がxタイプ であることが確実な場合はT、直接キャスト を使用する必要があります: (T)x。確実でない場合は を使用できますasが、何らかの操作を実行する前に を確認する必要があります。上記のコードが行うことは、 (有用な)を (役に立たない) にnull変換することだけです。InvalidCastExceptionNullReferenceException

これはキーワードの露骨な乱用だと思うのは私だけでしょうかas? それとも、私が何か明らかなことを見逃していて、上記のパターンは実際に意味をなしているのでしょうか?

ベストアンサー1

あなたの理解は正しいです。それは、マイクロ最適化を試みているように私には聞こえます。型が確実な場合は、通常のキャストを使用する必要があります。より合理的な例外を生成するだけでなく、失敗も早くなります。型についての仮定が間違っている場合、プログラムはすぐに失敗し、将来的にNullReferenceExceptionorArgumentNullExceptionまたは論理エラーが発生するのを待つのではなく、失敗の原因をすぐに確認できます。一般的に、どこかでチェックasが行われていない式は、nullコード臭です。

一方、キャストが確実でなく、失敗すると予想される場合は、ブロックasで囲まれた通常のキャストの代わりにを使用する必要がありますtry-catch。さらに、型チェックの後にキャストするよりも の使用がas推奨されます。 の代わりに:

if (x is SomeType)
   ((SomeType)x).SomeMethod();

生成するisinst命令キーワードとしてiscastclass命令キャスト(実質的にキャストを 2 回実行する)には、以下を使用する必要があります。

var v = x as SomeType;
if (v != null)
    v.SomeMethod();

これは命令を生成するだけですisinst。前者の方法は、マルチスレッド アプリケーションでは潜在的な欠陥があり、競合状態により、チェックが成功した後に変数の型が変更されis、キャスト行で失敗する可能性があります。後者の方法では、このエラーは発生しません。


次のソリューションは、実稼働コードでの使用は推奨されません。C# のこのような基本的な構造が本当に嫌な場合は、VB または他の言語に切り替えることを検討してください。

キャスト構文がどうしても嫌な場合は、キャストを模倣する拡張メソッドを書くことができます。

public static T To<T>(this object o) { // Name it as you like: As, Cast, To, ...
    return (T)o;
}

そして、きちんとした[?]構文を使用します:

obj.To<SomeType>().SomeMethod()

おすすめ記事