2011-10-30 11 views
2

私はEmailMessageというオブジェクトを持っています。このオブジェクトには、タイムスタンプと呼ばれるnull可能なSystem.DateTimeフィールドがあります。私のC#コードでは、次の行を持っています。C#条件演算子の戻り値の型

var TS = EmailMessage.Timestamp == null ? System.DateTime.Now : EmailMessage.Timestamp; 

なぜ.NET 4はSystem.DateTimeであるとTSのデータ型を推測しますか? System.DateTimeではなく、.NET4はTSがnullableであると思うのはなぜですか?TSは決してnullableではないことは私には明らかです。

ご協力いただきありがとうございます。

答えて

5

C#コンパイラは、単に

:-) DateTime.NowEmailMessage.Timestampの種類を見て、私はあなたに何かを教えてあげるので:私はあなたの仮定を破ることができました。 2つのスレッドがあるとしましょう。 1つのスレッドにはコードがあり、もう1つのスレッドにはEmailMessage.Timestamp = nullがあります。もう1つのスレッドはEmailMessage.Timestamp == nullTS = EmailMessage.Timestampの間で実行されます。 ?? OperatorにコンパイラがTSがNULL可能ではないことを知っているこの方法を使用して

var TS = EmailMessage.Timestamp ?? System.DateTime.Now; 

:私はあなたのコードは、通常はこのように書かれていることを追加します

:-)ブレイク。

+0

非常に明確な説明。ヌル合体オペレータについてのポインタをありがとう。 – Shredderroy

2

EmailMessage.TimestampがNullable<T>の場合、これが唯一有効なオプションです。真の場合、常に値を持つNullable<DateTime>になります。偽の場合、Timestampの値が仮定されます。値には値がある場合とない場合があります。

これ以上の分析は行われません。ただし、ヌル入力不可能なEmailMessage.Timestamp.Valueを使用することができます。

一般的に、プロパティは呼び出し間で値を変更する可能性があるため、nullをチェックして次回はnullにすることは安全ではありません。それはここでは起こりませんが、それがc#コンパイラが何の前提もしていない理由です。

ここで簡単な形成がおそらくある:。

var ts = EmailMessage.Timestamp ?? DateTime.Now; 
+0

複数のスレッドがある場合は、ここでも同じことが起こります。 –

+0

"の場合、タイムスタンプの値を仮定します。タイムスタンプの値は" - nah "である場合もありません。 'Timestamp'は常に値を持ちます。私はあなたの最初の段落が間違った方法かもしれないと思う。 –

+0

@Albinそれは、EmailMessageが何であるか(変数、フィールド、プロパティなど)によって異なりますが、あなたは正しくです –

2

DateTime?からDateTimeから暗黙の変換は、(あなたがcondition ? EmailMessage.TimeStamp : nullのような何かをした他の方法を、行くのとは対照的に、ありますので

しかし、あなたとにかくここでヌル合体演算子を使用する必要があります。

var TS = EmailMessage.TimeStamp ?? DateTime.Now 
+0

ヌル合体演算子について言及していただきありがとうございます。 – Shredderroy

1

代わりに、このようmething:

var TS = EmailMessage.TimeStamp == null ? DateTime.Now : EmailMessage.TimeStamp.Value; 

または多分

var TS = (EmailMessage.TimeStamp ?? DateTime.Now).Value; 
1

EmailMessage.Timestampは常にDateTime?です。ヌルかどうかを前にチェックしても問題ありません。コンパイラは気にしないで気にしないでください。マルチスレッドアプリケーションでは、EmailMessage.Timestampは、チェックと値の使用場所を変更することができます。コンパイラパースペクティブを作成するEmailMessage.Timestampは、後で使用するときにnullになり、タイプがDateTime?である必要があります。