0

次のコードがある場合

object o = new Building(4, "something");

そして、私は次のことを試みます

if(o.GetType() == typeof(Building))
    Building buildingCast = o as Building;

何がうまくいかない可能性がありますか?buildingCast問題のあるキャストからそれがnullになることは決してないことを確認したいと思います。そのキャストが失敗する可能性がある方法はありますか?何かあいまいなものでも?

私が尋ねる理由は、私がテストプロジェクトをクリーンアップしていて、冗長なコードを取り除こうとしているからです。buildingCastnullの可能性に対するチェックがあります...

if(buildingCast == null)
    etc

...しかし、ifステートメントのコードに到達することはできません。

4

5 に答える 5

4

リファクタリングのためにリファクタリングしないでください。次のコード行が連続している場合

object o = new Building(4, "something");
Building c = o as Building;

それならぜひ変更してください

Building o = new Building(4, "something");

でもあなたが

public void SomeMethod(object o)
{
   //you absolutely need a sanity check here
   Building c = o as Building;
   if( c == null )
      {
         //throw exception perhaps
      }

   //this can also be rewritten as
   Building b = null;
   if(o != null && o is Building)
          b = (Building)o;
   else
       //throw exception or log..etc

}

次のことを試みた場合

if(o.GetType == typeof(Building))
    Building buildingCast = o as Building;

次に、より冗長なものを作成します。実際、これによりコードが非常に読みにくくなります。次のようなことを行う必要があります。

Building buildingCast = null; //to be able to use outside the if
if(o.GetType() == typeof(Building))
        buildingCast = o as Building;

//you still end up with a null here if cast fails.
//this is the EXACT procedure of the 'as' operator anyway
//which does 
Building buildingCast = o is Building ? (Building)o : (Building)null;

..そしてもちろん、事前にチェックを使用してタイプが同じであることが絶対的に肯定的である場合、キャストは失敗しません。

于 2013-03-25T15:34:06.047 に答える
2

Building buildingCast = o as Building;

通常、この種のコードは、クラスが正しい型であるか(およびにキャストできるか)、またはnullであるかどうoかを知らずに、クラスをキャストするときに表示されます。Buildingo

次に、通常、nullチェックの後に表示されます。

これがすぐ上に表示された場合:

Building b  = new Building(4, "something");
object o = new Building(4, "something");

次に、asは冗長です。

ただし、oがシステムの他の部分から渡されている場合は、確信が持てないため、チェックします。

于 2013-03-25T15:26:47.260 に答える
2

の実際のタイプoがに割り当て可能である場合Building、これは機能します。実際のタイプに互換性がない場合は、null結果として取得されます。したがって、o上記の行以外の場所から来た場合は、そこにチェックを残す必要があります。

oタイプが100%確実である場合はBuilding、それをとして宣言しBuildingます。それが不可能な場合は、コードにチェックを残して、できるだけ早く1つにキャストする必要があります。たとえば、リフレクションを介してインスタンス化し、タイプがわかっている場合は、すぐにキャストする必要があります。

ところで、viaをキャストすると、asすでにタイプチェックが実行されます。タイプが該当しない場合は、を返しますnull

于 2013-03-25T15:28:22.027 に答える
1

as回答を読みましたが、キャストではないことを実際に指摘している人はいないようです。詳細については、 http://msdn.microsoft.com/en-us/library/vstudio/cscsdfbt.aspxを参照してください。

重要なセクションの引用:

as演算子は、参照変換、null許容変換、およびボクシング変換のみを実行することに注意してください。as演算子は、ユーザー定義の変換などの他の変換を実行できません。代わりに、キャスト式を使用して実行する必要があります。

少し説明的な(ただし100%正確ではない)用語を使用するとas、ポインターのタイプを変更しようとし、ポインターが別のタイプとして参照しているものを確認できるかどうかを確認しますが、キャスト演算子を呼び出そうとはしません。 、暗黙的かどうか。低レベルの観点からの大きな違い。

また、isここhttp://msdn.microsoft.com/en-us/library/scekt9xw(v=vs.80).aspxを参照することをお勧めします。これは、基本的obj.GetType() == typeof(sometype)にsteriods(および存在の問題objを取り除きnullます)。

一般asに、インターフェースに「変換」するときに使用します。as強制を許可しないため、オブジェクトは正しいタイプの実装である必要があります。

于 2013-03-25T16:09:01.703 に答える
0

これらの3行のコードは決して失敗しないはずです。

ただし、プログラムのどこかでバグが発生したり、誰かが関数を誤って呼び出したりしたために、予期しないパラメータで関数が呼び出される場合があります。

したがって、期待どおりの結果が得られたことを確認するためのチェックを行うことは常に良いことです。

于 2013-03-25T15:32:49.723 に答える