5

(标题中的“用户定义”是指加减法TimeSpanDateTime不是C#标准的一部分。它们在BCL中定义。)

在可空值TimeSpanDateTime值上使用提升运算符,我编写了以下代码。请注意,该框架在TimeSpan和上提供了不同的操作DateTime

有一个对称的(和可交换的)加法,你取两个TimeSpan并返回 sum TimeSpan。这种加法的“逆”是两个相减TimeSpan得到 a TimeSpan

然后是另一种加法,不对称,你需要一个DateTime(左操作数)和一个TimeSpan(右操作数)来产生一个DateTime. 由于此操作的不对称性,它有两种“逆”:一种是您将两个相减DateTime以获得TimeSpan差异,另一种是您有一个DateTime并从中减去一个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?(为什么不是long?顺便说一句?)虽然是不允许的,这有点奇怪g。这在规范中吗?c此外,通过字符串连接解决“不可能”有点奇怪。显然编译器决定nullinc是一个(string)null. 另一方面,将显式类型的表达式添加object到 a将不会编译。DateTime

但我的主要问题是:为什么编译器可以为dand选择重载l,但m它抱怨歧义?

4

1 回答 1

0

原因似乎是,m两个可能的操作被定义在同一个类型中,即System.DateTime。没有办法在它们之间做出选择。

另一方面,使用dl,一个操作定义在 中,另一个操作定义System.TimeSpan在 中System.DateTime。但是在 and 的行中dl我们看到了,但是在and的分配中TimeSpan没有提到任何类型。然后编译器似乎只搜索 type 中定义的运算符,而忘记搜索所有其他类型中定义的用户定义运算符(顺便说一句,要搜索的类型非常多)。这样,在解析and期间,编译器永远不会发现类型内部定义的运算符。DateTimedlSystem.TimeSpandlDateTime

于 2012-10-25T16:15:31.837 回答