0

次のプログラムが警告なしでコンパイルされる理由がわかりませんが、例外ブロックで条件演算子が NullReferenceException を返します。

using System;

namespace Playground
{
    class Program
    {
        static void Main(string[] args)
        {
            string message1 = "First message.";
            string message2 = null;
            // This works without a problem
            Console.WriteLine(message1 + message2 == null ? "" : Environment.NewLine + message2);
            Console.ReadKey();

            try
            {
                throw new Exception("Now with an exception.");
            }
            catch (Exception ex)
            {
                // This will give a NullReferenceException:
                Console.WriteLine(ex.Message + ex.InnerException == null ? "" : Environment.NewLine + ex.InnerException.Message);
                // ..But this will work:
                Console.WriteLine(ex.Message + (ex.InnerException == null ? "" : Environment.NewLine + ex.InnerException.Message));
            }
        }
    }
}

演算子については知ってい??ます。質問は、例外ハンドラの最初の行で NullReferenceException が発生する理由についてです。

4

2 に答える 2

4
ex.Message + ex.InnerException

に変換されます

string.Concat(ex.Message, ex.InnerException);

これは、引数が null かどうかをチェックし、そうでない場合にのみ文字列に変換します。この意味は

ex.Message + ex.InnerException == null

false表現はそうです

Environment.NewLine + ex.InnerException.Message

評価されます。ex.InnerExceptionnull であるため、これは例外をスローします。

于 2014-07-01T08:12:11.990 に答える
1

InnerExceptionが null であるがそうでない場合ex.Message、最初の式は に評価され、これfalseにアクセスしようとします。ex.InnerException.MessageNullReferenceException

2番目の式では、がnullでない場合にex.InnerException.Message のみアクセスしようとしているため、機能します..ex.InnerException

NullReferenceExceptionnull のメンバー(メソッド、プロパティ、フィールドなど)にアクセスしようとすると発生しますobject。最初の例では:

message1 + message2 == null ? "" : Environment.NewLine + message2;

新しい行を連結していて、のmessage2プロパティやメソッドにアクセスしていませんmessage2。null 値に空の文字列を追加するだけです。次のドキュメントをご覧string.Concatください。

メソッドは str0 と str1 を連結します。区切り文字は追加されません。null 引数の代わりに空の文字列が使用されます

あなたが書く場合:

message1 + message2 == null ? "" : Environment.NewLine + message2.ToString();

その後、例外が発生します。

于 2014-07-01T08:09:50.620 に答える