("do người dùng xác định" trong tiêu đề đề cập đến việc cộng và trừ TimeSpan
và DateTime
không phải là một phần của tiêu chuẩn C#. được xác định trong BCL.)Độ phân giải quá tải nghiêm trọng khi sử dụng chữ cái rỗng không xác định với toán tử do người dùng xác định
Chơi xung quanh với toán tử được dỡ bỏ trên giá trị TimeSpan
và DateTime
không có giá trị, tôi đã viết mã sau đây. Lưu ý rằng khung công tác cung cấp các hoạt động khác nhau trên TimeSpan
và DateTime
.
Có một phép cộng đối xứng (và giao hoán) mà bạn nhận được trong hai số TimeSpan
và trả lại số tiền TimeSpan
. "Nghịch đảo" của phần bổ sung này là phép trừ của hai số TimeSpan
cho một số TimeSpan
.
Sau đó, có một loại bổ sung, không đối xứng, nơi bạn lấy một DateTime
(toán hạng bên trái) và một TimeSpan
(toán hạng bên phải) để tạo ra một DateTime
. Do tính bất đối xứng của thao tác này, nó có hai "loại" của các nghịch đảo: Một trong đó bạn trừ hai số DateTime
khỏi nhau để có chênh lệch TimeSpan
và một nơi bạn có một số DateTime
và trừ nó TimeSpan
để tạo ra kết quả 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;
}
Một số câu hỏi phát sinh một cách tự nhiên.
Có một chút lạ là o
được phép và cung cấp cho int?
(tại sao không phải là long?
bằng cách này?) Trong khi g
không được phép. Đây có phải là thông số kỹ thuật không? Ngoài ra, có một chút lạ là "không thể" c
được giải quyết bằng cách nối chuỗi. Rõ ràng trình biên dịch quyết định rằng null
trong c
là (string)null
. Việc thêm một biểu thức loại rõ ràng object
vào một DateTime
, mặt khác, sẽ không biên dịch.
Nhưng câu hỏi chính của tôi là: Tại sao trình biên dịch có thể chọn một tình trạng quá tải cho d
và l
, nhưng với m
nó than phiền về sự mơ hồ?
Cho đến nay điều kỳ lạ nhất ở đây là var o = null - null; –
'c' sử dụng nối chuỗi vì các toán tử ngôn ngữ được ưu tiên hơn các toán tử do người dùng định nghĩa, và biểu thức đó khớp với toán tử nối chuỗi của toán tử' + (chuỗi, đối tượng) '. Điều đó tất nhiên đặt ra câu hỏi của 'd' mặc dù, như logic đó cũng nên giải quyết để nối chuỗi. – Servy
@DaveBish Đồng ý. Tôi cho rằng nó sẽ là mơ hồ giữa int/long – Servy