==가 null 값에 대해 true를 반환 할 때> =가 false를 반환하는 이유는 무엇입니까?


78

int 유형의 두 변수가 있습니까? (또는 원하는 경우 Nullable <int>). 두 변수에 대해 크거나 같음 (> =) 비교를 원했지만 두 변수가 모두 null이면 false를 반환하고 == 연산자는 true를 반환합니다.

> = 연산자의 의미 론적 정의에 "or"라는 단어가 포함되어 있기 때문에 이것이 왜 논리적인지 설명해 줄 수 있습니까?


1
이 이상한 동작을 생성하는 코드를 게시 할 수 있습니까?
Android Eve

12
실제로 ==가 true를 반환하는 것이 적절한 지 질문합니다. 나는 그것이 전혀 적절하지 않다고 생각합니다. 값을 알 수없는 두 변수를 어떻게 동일하게 인증 할 수 있습니까?
Charles Bretana

2
@Charles, 동일한 null 유형 (예 :) int?이면 해당 값 알려져 있기 때문 입니다. null.
Moo-Juice

3
@ moo-juice, Not in my world ... 네 이름이 null이면 대답 해 줄래? null은 "null"과 동일하지 않습니다. "내 이름은 아무도 없다"라는 오래된 영화가 있습니다. ( "누가 유리 잔을 깨뜨 렸나요?"---- "아무도") 그럼 "아무도"는 누구입니까? 실제 세계에서 (코드 내부 외부), null은 값을 알 수 없음을 의미합니다 .... 데이터 구조 값은 알 수 있지만 (일 수 Null있지만) 변수가 나타내는 실제 문제 도메인 엔티티 / 값은 다음과 같습니다. 알 수 없음 ..
Charles Bretana

2
@Charles, 비유를 사랑하십시오!. 하지만 누가 유리를 깨지 않았 습니까?
Moo-Juice

답변:


97

이 기능이 원래 C # 2.0으로 다시 설계되었을 때이 이상한 점에 대해 큰 논쟁이있었습니다. 문제는 C # 사용자가이 의미에 완전히 익숙하다는 것입니다.

if(someReference == null)

동등성을 nullable 값 유형으로 확장 할 때 다음을 선택할 수 있습니다.

  1. Nullable 평등이 진정으로 해제 됩니다. 피연산자 중 하나 또는 모두가 널이면 결과는 참도 거짓도 아닌 널입니다. 이 경우 다음 중 하나를 수행 할 수 있습니다.

    • a) ifif에 nullable bool이 아닌 bool이 필요 하기 때문에 문 에 nullable 값 유형이 같음을 갖는 것은 불법으로 만듭니다 . 대신 HasValuenull과 비교 하려면 모든 사람이 사용하도록 요구하십시오 . 이것은 장황하고 자극적입니다.

    • b) 자동으로 null을 false로 변환합니다. 이것의 단점은 x==nullx가 null 인 경우 false 를 반환 한다는 것입니다 . 이는 혼란스럽고 참조 유형과의 null 비교에 대한 사람들의 이해에 위배됩니다.

  2. Nullable 동등성은 해제되지 않습니다. Nullable 같음은 true 또는 false이고 null과의 비교는 null 검사입니다. 이로 인해 nullable 같음이 nullable 부등식과 일치하지 않게됩니다.

이러한 선택 중 어느 것도 분명히 정확하지 않습니다. 그들은 모두 장단점이 있습니다. 예를 들어 VBScript는 1b를 선택합니다. 많은 논쟁 끝에 C # 디자인 팀은 # 2를 선택했습니다.


nullable 평등이 선택 # 2의 nullable 불평등과 어떻게 일치하지 않습니까?
MCS

3
@MCS : 애초에 질문에 동기를 부여하는 방식입니다. ==는 <=가 거짓 일 때 참일 수 있습니다.
Eric Lippert

@Eric : 감사합니다-나는 '불평등'이 실제로 ==와 일치하는! =만을 언급한다고 생각했습니다. 그것이 수학 용어 인 것을 몰랐습니다 : en.wikipedia.org/wiki/Inequality_(mathematics) .
MCS

1
음, (당신이 언급하지 않은) 다른 문제는 당신이하려고 할 때 무엇이다 <, <=, =>, 또는 >피연산자 중 하나가 될 때 null. C #에서 대답은 return false입니다. Scala / Java String클래스에서 대답은 NullPointerException.
Ken Bloom

3
@Brian : 그렇다면 왜 nullable 형식에 대한 연산자를 허용합니까? 그들이 항상 nullable 형식의 null 값을 던지면 nullable이 아닌 형식에만 연산자를 정의하고 사용자가 nullable이 아닌 변환을 삽입하도록 할 수 있습니다. 예외를 제거하려면 수행하십시오.
Eric Lippert

60

Equality는 Comparability와 별도로 정의되기 때문입니다.
테스트 할 수는 x == null있지만 x > null의미가 없습니다. C #에서는 항상 false입니다.


1
+1 : 여기에 MSDN 링크 msdn.microsoft.com/en-us/library/2cf62fcy.aspx가 있습니다 . 그러나 불행히도 2 개의 null (동등성 만 언급 함)의 경우 비교 연산자 동작을 설명하는 것을 잊었습니다 ...
digEmAll

3
예, 그러나 연산자는 크 거나 같습니다. 진리표를 보았지만 OP에 동의하는 경향이 있습니다.> =는 크 거나 같으며, null == null이 true이면 null> = null도 true 여야합니다. == null 검사를 유지하기 위해 구현 및 사용자 편의에 중점을 두는 것 같습니다.
BlackICE

2
@David, Eric의 대답, "이 선택 중 어느 것도 분명히 정확하지 않습니다."를 참조하십시오. 그러나 일반적으로 유형이 Equatable이지만 Comparable >=이 아닌 경우 단순히 정의되지 않습니다.
Henk Holterman

11

'> ='를 설명하는 또 다른 방법은 Not Less Than입니다. 동등에 대한 언급이 없습니다. 비동 등 테스트의 피연산자 중 하나가 Null이면 결과도 알 수 없습니다 (null 임). 그러나 두 피연산자가 모두 Null인지 알고 싶다면 Null == Null이 합리적인 테스트입니다 (결과가 true 여야 함). 연산자의 불평등 부분을 제거하는 것이 모든 차이를 만듭니다.

http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx#sectionToggle4 의 다음 코드 예제는 C #에서 Null을 처리하는 방법을 요약합니다.

int? num1 = 10;   
int? num2 = null;   
if (num1 >= num2)   
{   
    Console.WriteLine("num1 is greater than or equal to num2");   
}   
else   
{   
    // This clause is selected, but num1 is not less than num2.   
    Console.WriteLine("num1 >= num2 returned false (but num1 < num2 also is false)");   
}   

if (num1 < num2)   
{   
    Console.WriteLine("num1 is less than num2");   
}   
else   
{   
    // The else clause is selected again, but num1 is not greater than   
    // or equal to num2.   
    Console.WriteLine("num1 < num2 returned false (but num1 >= num2 also is false)");   
}   

if (num1 != num2)   
{   
    // This comparison is true, num1 and num2 are not equal.   
    Console.WriteLine("Finally, num1 != num2 returns true!");   
}   

// Change the value of num1, so that both num1 and num2 are null.   
num1 = null;   
if (num1 == num2)   
{   
    // The equality comparison returns true when both operands are null.   
    Console.WriteLine("num1 == num2 returns true when the value of each is null");   
}   

/* Output:   
 * num1 >= num2 returned false (but num1 < num2 also is false)   
 * num1 < num2 returned false (but num1 >= num2 also is false)   
 * Finally, num1 != num2 returns true!   
 * num1 == num2 returns true when the value of each is null   
 */   

그것은 흥미로운 멘탈 모델입니다. 그러나 C # 사양의 섹션 §1.4는 이러한 연산자를 Less Than Or Equal 및 Greater than or equal이라고 부릅니다.
Conrad Frix

3
@Conrad 이것은 프로그래밍 언어 (이 경우 C #)를 영어로 번역하는 문제를 보여줍니다. IMHO, Null이 논리로 간주 될 때마다 3 가지 상태 결과 (참, 거짓, 알 수 없음)를 처리 해야 합니다. Null을 포함하는 모든 표현식은 알 수 없음이되어야합니다. 단, 알 수 없음에 Null == x대한 명시 적 테스트는 참 또는 거짓 결과입니다.
NealB

@NealB : 실제로, 사양은> = 및 <=가 의미하는 바를 의미한다고 명시합니다. 섹션 §7.10은 <= 및> =에 대한 'x op y'연산이 동일 함을 의미합니다. 에 또는 보다 큰 / 덜보다, 하나 기대하는 것처럼.
nicodemus13

2

>=숫자 값에서 작동합니다. null이 아닙니다.

당신은 할 수 과부하>= 특정 유형에 원하는 것을 제공하는 연산자.


null 유형에서 작동하며 false를 반환합니다.
BlackICE

그것은 우리가 "operates"로 정의 할 것에 대한 예 ... 의미 널 유형을 처리합니다. 방어 적 코딩; 평가 중에 결정을 내릴 때 null을 리터럴 값으로 처리하는 대신 x를 수행하십시오.
Aaron McIver

일반적으로 연산자는 자체 클래스 내에서만 정의 할 수 있으므로 오버로드 할 수 없습니다. 따라서이 경우 Nullable<T>의 코드에 액세스해야 합니다.
ANeves은 SE입니다 생각하는 악

0

NULL은 0 (숫자 또는 2 진 값), 길이가 0 인 문자열 또는 공백 (문자 값)이 아닙니다. 따라서 모든 비교 연산자는 항상 false를 반환합니다. 여기에서 자세히 알아보세요.


8
데이터베이스 NULL은 C #이 아닙니다 null. 또한 C # nullable 형식의 비교 연산자는 null 비교에 대한 일반적인 규칙을 반드시 따르지 않는 이상한 짐승입니다.
Joren

3
대답은 여전히 ​​옳고 링크가 잘못되었습니다. msdn.microsoft.com/en-us/library/2cf62fcy.aspx#sectionToggle4
unholysampler 2010

5
@unholy : 대답은 틀렸고, 더 중요한 것은 잘못된 추론을 기반으로한다는 것입니다.
Joren

0

어떤 가치를 기대하십니까?

null == null 참

null> = null false

null> null false

null <= null false

null <null false

null! = null false

1 == null 거짓

1> = null 거짓

1> null 거짓

1 <= null 거짓

1 <null 거짓

1! = null true aka! (1 == null)


0

> =는 잘 정의 된 특정 방식으로 사용될 때 "크거나 같음"만을 의미합니다. 오버로드 된 연산자가있는 클래스에서 사용되면 클래스 개발자가 원하는 모든 것을 의미합니다. 문자열과 같은 클래스에 적용될 때 "동일하거나 더 높은 정렬"을 의미하거나 "동일한 길이 또는 더 긴"을 의미 할 수 있습니다.


0

기본적으로는 intnull 일 수 없으며 해당 값은로 설정 0되므로 int유형에 대해 빌드 된> 및 <연산자 는에서 작동하지만에서 작동 values하지 않을 것으로 예상합니다 nulls.

및 연산자 https://stackoverflow.com/a/51507612/7003760 을 처리 nullable int하는 몇 가지 방법을 작성한 비슷한 질문에 대한 내 대답을 참조 하십시오.less <greater >

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.