먼저의 질문을 명확히 할 수 있습니다.
C# 1.0에는 값 유형 (null이 아님)과 참조 유형 (null 입력 가능)의 두 가지 범주가있었습니다.
*
값과 참조 타입 모두 인스턴스와 연관된 값을 선택하는 부재 액세스 연산자, .
을 지원한다.
참조 유형의 경우 .
연산자와 수신기의 null 허용 여부는 수신기가 null 참조 인 경우 .
연산자를 사용하면 예외가 발생합니다. C# 1.0 값 유형은 처음에는 nullable이 아니기 때문에 .
null 값 유형 일 때 어떤 일이 발생하는지 지정할 필요가 없습니다. 그들은 존재하지 않는다.
C# 2.0에서는 null 값 유형이 추가되었습니다. Nullable 값 유형은 메모리 내 표시가 나타나는 한 마술 같은 것이 아닙니다. 값의 인스턴스가있는 구조체이고 null인지 아닌지를 나타내는 bool입니다.
nullable 값 유형이 리프팅 의미와 일치하므로 컴파일러 마법 (**
)이 있습니다..리프팅 우리는 nullable 값 형식의 연산에 "값이 null이 아니고 값에 연산을 수행하고 결과를 Nullable 형식으로 변환합니다. 그렇지 않으면 결과가 null입니다"라는 의미를 가짐을 의미합니다. (***
)
우리는 컴파일러가 효율적으로 해제 연산을 구현하는 마법의 모든 종류를하고있는 장면 뒤에
int? x = 2;
int? y = 3;
int? z = null;
int? r = x + y; // nullable 5
int? s = y + z; // null
이있는 경우, 말을하는 것입니다
; see my lengthy blog series on how I wrote the optimizer if this subject interests you.
그러나 .
연산자는 이 아니며이 해제되었습니다. 그것은 수! 수신기가 null의 경우 예외를 던져, 또는
그것은 널 (NULL) 연산처럼 행동 수 :
nullable.Whatever()
이 같은 널 (NULL) 참조 형식으로 동작 할 수 않습니다이 이해하기 적어도 두 가지 디자인은 nullable
가 null의 경우 Whatever()
에 대한 호출이 생략되고 결과는 Whatever()
이 반환 한 모든 유형의 null입니다.
그래서 질문은 : 합리적인 디자인 그냥 작동 및 기본 유형의 멤버를 추출하는 .
운영자가있을 때
왜 .Value.
을 필요로?
음.
내가 방금 한 일에 주목하십시오. 두 가지 가능성이 모두 완벽하게 이해되며 언어의 확립되고 잘 이해 된 측면과 일치하며 서로 상반됩니다. 언어 디자이너들은 항상 의 지팡이에 자신을 발견합니다.. nullable 값 형식의 .
이 참조 형식에서 .
처럼 동작해야하는지 또는 .
이 nullable int에 +
처럼 동작해야하는지 여부는 완전히 알 수없는 상황에 처해 있습니다. 둘 다 그럴듯 해. 어느 것이 든 집어 들었을 때 누군가가 잘못되었다고 생각할 것입니다.
언어 디자인 팀에서는 명시 적으로 지정하는 등의 대안을 고려했습니다. 예를 들어, "Elvis"?.
연산자는 명시 적으로 null 값으로 올릴 수있는 멤버 액세스 권한입니다. 이것은 C# 2.0에서 고려되었지만 거부되었고 결국 C# 6.0에 추가되었습니다. 고려 된 몇 가지 다른 통사론 적 해결책이 있었지만 모두 역사적으로 손실 된 이유로 거부당했습니다.
이미 값 유형에 .
에 대한 잠재적 인 설계 지뢰밭이 있지만 대기 상태가 악화됨을 알았습니다. 값 형식에 적용 할 때
하는의 지금 .
의 또 다른 측면을 살펴 보자 : 값 유형이 끔찍한 가변 값 유형이며, 회원이 필드 경우, 다음 x.y
는 변수x
경우입니다 변수이고, 그렇지 않으면 값입니다. 즉, x
이 변수 인 경우 x.y = 123
이 유효합니다.그러나 x
이 변수가 아니면 값이 사본에 지정되므로 C# 컴파일러는 할당을 허용하지 않습니다.
이 값은 nullable 값 유형과 어떤 관련이 있습니까? nullable 변경할 수있는 값 유형이있는 경우
x.y = 123
할 수 있습니까? x
정말 불변 유형 Nullable<X>
의 인스턴스이기 때문에이 x.Value.y = 123
다음 을 의미한다면 우리는 매우, 매우 잘못된 것 같습니다 Value
재산에 의해 반환되는 값의 복사본을 돌연변이있다 기억하십시오.
그럼 어떻게해야합니까? nullable 값 유형을 스스로 변경할 수 있어야합니까? 그 돌연변이는 어떻게 작동할까요? copy-in-copy-out 의미론입니까? 이는 ref
이 속성이 아니라 변수를 요구하기 때문에 ref x.y
이 불법이라는 것을 의미합니다.
거대한 freakin '엉망 될 수 있습니다.
C# 2.0에서는 디자인 팀이 제네릭을 언어에 추가하려고 시도했습니다. 기존 유형 시스템에 제네릭을 추가하려고 시도한 적이 있다면 얼마나 많은 작업인지 알 수 있습니다. 그렇지 않다면, 그것은 많은 일을합니다. 디자인 팀은이 모든 문제에 대해 펀트를 결정할 수있는 패스를 부여 받아 .
에 nullable 값 유형에 특별한 의미가 없다고 생각합니다. "가치를 원한다면 .Value
이라고 부릅니다."디자인 팀 측에서는 특별한 작업이 필요 없다는 이점이 있습니다! 그리고 비슷하게, "가변적 인 nullable 값 유형을 사용하는 것이 상처라면, 아마도 그 일을 그만 두십시오"라는 것은 디자이너에게는 저렴한 비용입니다.
우리가 다음 우리는 두 C# 1.0 유형의 직교가지했을 것이다 완벽한 세계에 살고있는 경우 : nullable이 아닌 유형의 대 값 형식에 대 참조 유형 및 nullable 형식을. 우리가 얻은 것은 nullable 참조 형식과 C# 1.0의 nullable 값 형식, C# 2.0의 nullable 값 형식 및 10 년 반 후 C# 8.0의 nullaable 참조 형식입니다.
완벽한 세계에서 우리는 모든 연산자 의미론, 의미 지우기, 변수 의미론 등을 정렬하여 을 모두 한 번에으로 일관되게 만듭니다.
하지만 우리는 완벽한 세상에 살지 않습니다. 우리는 완벽한 것이 적의 적이며, C# 2.0에서 5.0까지는 .
대신에 .Value.
, C# 6.0에서는 ?.
대신에 .Value.
을 써야합니다.
*
나는 의도적으로 널 (NULL)과 값 형식의 일부 특성과 참조 타입의 몇 가지 특성을 가지고 있고, 역 참조 및 멤버 액세스에 대한 자신의 특별한 연산자를 가지고있는 포인터 유형을 무시하고있다.
**
nullable 값 형식은 값 형식 제약 조건, nullable 값 형식 상자를 null 참조 또는 boxed 기본 형식 및 기타 많은 작은 특수 동작을 수행하지 않는 것과 같은 항목에 마법이 있습니다. 그러나 메모리 레이아웃은 불가사의 한 것은 아닙니다. 그것은 단지 bool 옆에있는 값입니다.
***
기능 프로그래머는 물론 모나드의 바인드 작업임을 알고 있습니다.
어, 값을 어떻게 읽을 수 있습니까? – maccettura
그 대신에 무엇을 제안합니까? – Servy
왜 객체에 직접 점을 찍을 수 없습니까? –