5

TimeSpan(タイトルの「ユーザー定義」とは、 と の加算と減算が C# 標準の一部ではないという事実を指しDateTimeます。それらは BCL で定義されています。)

nullableTimeSpanDateTime値の持ち上げられた演算子をいじって、次のコードを書きました。フレームワークは と で異なる操作を提供することに注意してTimeSpanくださいDateTime

TimeSpan2 つを取り、 sum を返す、1 つの対称 (および可換) 加算がありますTimeSpan。この加算の「逆」は、TimeSpanを生成する2 の減算ですTimeSpan

次に、別の種類の加算、非対称があります。ここでは、1 つDateTime(左オペランド) と 1 つTimeSpan(右オペランド) を使用して を生成しDateTimeます。この演算は非対称であるため、2 つの「種類」の逆行列があります。1 つDateTimeは互いに 2 を減算してTimeSpan差を求めるもの、もう 1 つは 1 を取り、そこから 1DateTimeを減算してTimeSpan結果を生成するものDateTimeです。

static void Main()
{
  DateTime? n_dt = new DateTime(2012, 12, 25);
  TimeSpan? n_ts = TimeSpan.FromDays(62.0);

  var a = n_dt + n_ts;   // OK
  var b = n_ts + n_ts;   // OK

  var c = null + n_dt;   // OK, string concatenation! Type of expression is String
  var d = null + n_ts;   // OK, compiler prefers TS+TS, not DT+TS
  var e = n_dt + null;   // OK, DT+TS
  var f = n_ts + null;   // OK, TS+TS
  var g = null + null;   // error, type of expression is undetermined

  var h = n_dt - n_dt;   // OK
  var i = n_dt - n_ts;   // OK
  var j = n_ts - n_ts;   // OK

  var k = null - n_dt;   // OK, DT-DT
  var l = null - n_ts;   // compiler prefers TS-TS, not DT-TS
  var m = n_dt - null;   // error, compiler won't choose between DT-DT amd DT-TS, type of expression is undetermined
  var n = n_ts - null;   // OK, TS-TS
  var o = null - null;   // OK, integer subtraction! Type of expression is Nullable<Int32>

  // illegal:
//var p = n_dt + n_dt;
//var q = n_ts + n_dt;
//var r = n_ts - n_dt;
}

自然にいくつかの疑問が生じます。

o許可されているのにint?(ちなみに a ではないのはなぜlong?ですか?) whilegが許可されていないのは少し奇妙です。これは仕様でしょうか?あと、文字列連結で「ありえない」cが解消されるのもちょっと不思議。どうやらコンパイラはnullinc(string)null. 一方、明示的な型の式objectを aに追加すると、コンパイルされません。DateTime

しかし、私の主な質問は、コンパイラandのオーバーロードを選択できるのはなぜですか?dlm

4

1 に答える 1

0

その理由はm、 では、2 つの可能な操作が同じ型、つまり 内で定義さSystem.DateTimeれているためと思われます。それらから選択する方法はありません。

一方、dlでは、一方の操作は で定義されSystem.TimeSpan、もう一方の操作は で定義されSystem.DateTimeます。しかし、dandの行には がl表示されますが、 andの代入では、どのような型TimeSpanについても言及されていません。コンパイラは、 type で定義された演算子のみを検索し、他のすべての型で定義されたユーザー定義の演算子を検索するのを忘れているようです (ちなみに、検索する型は非常に多くなります)。そのようにして、 と の解決中に、コンパイラは型内で定義された演算子を決して検出しません。DateTimedlSystem.TimeSpandlDateTime

于 2012-10-25T16:15:31.837 に答える