5

(제목에서 "사용자 정의"는 TimeSpanDateTime의 더하기 및 빼기가 C# 표준의 일부가 아니라는 것을 의미합니다. BCL에 정의되어 있습니다.사용자 정의 연산자로 Naked null 리터럴을 사용하는 경우의 이상한 오버로드 해결

nullable TimeSpanDateTime 값에서 올림 된 연산자를 사용하여 다음 코드를 작성했습니다. 프레임 워크는 TimeSpanDateTime에서 다른 작업을 제공합니다.

TimeSpan 두 개를 넣고 TimeSpan을 반환하는 대칭 (및 교환 가능) 추가가 있습니다. 이 덧셈의 "역 (inverse)"은 TimeSpan을 뺀 TimeSpan을 뺀 것입니다.

는 그런 다음 DateTime를 생산하는 하나 DateTime (왼쪽 피연산자)와 하나의 TimeSpan (오른쪽 피연산자) 걸릴뿐만 아니라, 비대칭, 다른 종류가있다. 이 연산의 비대칭 성 때문에 두 개의 "반전"종류가 있습니다 : 하나는 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이 문자열 연결로 해결되는 것이 약간 이상합니다. 컴파일러는 null (c)이 (string)null 인 것으로 판단합니다. 반대로 명시 형 object의 표현식을 DateTime에 추가하면 컴파일되지 않습니다. 왜 컴파일러가 dl에 대한 과부하를 선택할 수 있지만 m으로는 모호함에 대해 불평 :

하지만 내 주요 질문은?

+3

여기서 가장 이상한 것은 var o = null - null입니다. –

+0

'c'는 언어 연산자가 사용자 정의 연산자보다 선호되고 그 표현식이'operator + (string, object)'의 문자열 연결 연산자와 일치하기 때문에 문자열 연결을 사용합니다. 물론 문자열 연결로 해결해야하는 논리에 따라 'd'에 대한 질문이 제기됩니다. – Servy

+0

@DaveBish 동의. 나는 int/long 사이에 애매한 것이라고 가정한다. – Servy

답변

0

이유 m으로 상기 두 가지 작업은 동일한 종류의 내부 정의 System.DateTime이다 것 같다. 그들 사이에서 선택할 방법이 없습니다. d과 함께 l 한편

는 번 동작 System.TimeSpan에서 정의되고, 다른 하나는 System.DateTime 정의된다. 그러나 dl 행에는 TimeSpan이 표시되지만 및 l의 과제에는 어떤 것이 있는지 DateTime 유형에 대한 언급이 없습니다. 그런 다음 컴파일러가 System.TimeSpan 유형으로 정의 된 연산자를 검색하고 다른 모든 유형에 정의 된 사용자 정의 연산자를 검색하는 것을 잊어 버리는 것처럼 보입니다 (그런데 매우 많은 유형의 검색이 될 것입니다). 그런 식으로 dl의 해결 중에 컴파일러는 DateTime 형식 내에 정의 된 연산자를 절대로 발견하지 못합니다.

+1

C# 스펙의 7.3.4 절을 참조하십시오. 관련성이 있으며이 대답을 확인할 수 있습니다. – Servy

+0

"그건 그렇고"실제로. – phoog