IT이야기

널 리터럴의 유형

cyworld 2021. 3. 30. 21:36
반응형

널 리터럴의 유형은 무엇입니까?


귀 모두, nullC #에서 리터럴 유형이 무엇인지 궁금합니다 .

Java에서 null리터럴 은 특수한 null 유형입니다 .

이름이없는 표현식의 유형 인 특수 널 유형 도 있습니다 null. 널 유형에는 이름이 없기 때문에 널 유형의 변수를 선언하거나 널 유형으로 캐스트 할 수 없습니다. 널 참조는 널 유형 표현식의 유일한 가능한 값입니다. 널 참조는 항상 모든 참조 유형으로 캐스트 될 수 있습니다.

C ++ 11에는 nullptr(이전 친구의 권장 버전 NULL) 유형이std::nullptr_t 있습니다.

C #에 대해 MSDN을 검색했지만 사양 에는 그것에 대해 아무 말도하지 않는 것 같습니다.


ECMA C # 언어 사양 에 따르면 :

9.4.4.6 널 리터럴 :

null-literal의 형식은 null 형식 (§11.2.7)입니다.

11.2.7 널 유형 :

null 리터럴 (§9.4.4.6)은 개체 나 배열을 가리 키지 않는 참조 또는 값이 없음을 나타내는 데 사용되는 null 값으로 평가됩니다. 널 유형에는 널값 인 단일 값이 있습니다. 따라서 유형이 널 유형 인 표현식은 널 값으로 만 평가할 수 있습니다. null 유형을 명시 적으로 작성할 수있는 방법이 없으므로 선언 된 유형에서 사용할 방법이 없습니다. 또한 null 형식은 형식 매개 변수에 대해 유추 된 형식이 될 수 없습니다 (§25.6.4).

따라서 귀하의 질문에 답하기 위해 null은 자체 유형입니다-null 유형.

C # 4.0 언어 사양 또는 C # 3.0 언어 사양 에는 언급되지 않았지만 C # 3.0 개요 , ECMA C # 언어 사양C # 2.0 언어 사양 에서는 언급되지 않는 것이 이상 하지만 .


업데이트 : 이 질문은 2013 년 7 월 내 블로그의 주제였습니다. 좋은 질문에 감사드립니다!


J.Kommer의 대답은 정확하지만 (분명히 많은 사양을 파는 작업을 수행하는 데 적합합니다!) 약간의 역사적 관점을 추가 할 것이라고 생각했습니다.

Mads와 내가 C # 3.0 사양의 다양한 부분에 대한 정확한 표현을 분류 할 때 "null 유형"이 기이하다는 것을 깨달았습니다. 값이 하나 뿐인 "유형"입니다. Reflection이 알지 못하는 "유형"입니다. 이름이없고 GetType이 반환하지 않는 "유형"이며 지역 변수 나 필드 또는 그 밖의 유형으로 지정할 수 없습니다. 요컨대, 그것은 유형 시스템을 "완전하게"만들기 위해서만 존재하는 "유형"이므로 모든 컴파일 타임 표현식은 유형을 갖습니다.

C #에는 C # 1.0의 메서드 그룹, C # 2.0의 익명 메서드 및 C # 3.0의 람다 모두 형식이없는식이 이미있는 것을 제외하고는 모두 형식이 없습니다. 이러한 모든 것들이 유형을 가질 수 없다면 "null"도 유형을 가질 필요가 없다는 것을 깨달았습니다. 따라서 C # 3.0에서 쓸모없는 "null 형식"에 대한 참조를 제거했습니다.

구현 세부 사항으로 C # 1.0에서 5.0까지의 Microsoft 구현에는 모두 "null 형식"을 나타내는 내부 개체가 있습니다. 또한 존재하지 않는 유형의 람다, 익명 메서드 및 메서드 그룹을 나타내는 개체도 있습니다. 이 구현 선택에는 여러 장단점이 있습니다. 프로 측면에서 컴파일러는 모든 표현식의 유형을 요청하고 답을 얻을 수 있습니다. 단점은 컴파일러를 충돌시켜야하는 유형 분석의 버그로 인해 프로그램의 의미가 변경되는 경우가 있습니다. 제가 가장 좋아하는 예는 C # 2.0에서 "null ?? null"이라는 잘못된 표현을 사용할 수 있다는 것입니다. 버그로 인해 컴파일러는 잘못된 사용법으로 플래그를 지정하지 못합니다.??이 표현식의 유형이 널 리터럴이 아니더라도 "널 유형"이라고 추론합니다. 그런 다음 유형 분석기가 유형을 이해하려고 시도함에 따라 다른 많은 다운 스트림 버그가 발생합니다.

Roslyn에서는이 전략을 사용하지 않을 것입니다. 오히려 일부 표현식에 유형이없는 컴파일러 구현을 간단히 적용 할 것입니다.


런타임 유형 null이 없더라도이 예제에서 볼 수 있듯이 컴파일 타임에 유형으로 캐스트 할 수 있습니다.

런타임시, 해당 변수를 찾을 수 stringAsObject보유 string하지 만 object,하지만 당신은 변수에 대한 모든 유형 찾을 수 없습니다 nullStringnullStringAsObject.

public enum Answer { Object, String, Int32, FileInfo };
private Answer GetAnswer(int i) { return Answer.Int32; }
private Answer GetAnswer(string s) { return Answer.String; }
private Answer GetAnswer(object o) { return Answer.Object; }

[TestMethod]
public void MusingAboutNullAtRuntimeVsCompileTime()
{
    string nullString = null;
    object nullStringAsObject = (string)null;
    object stringAsObject = "a string";

    // resolved at runtime
    Expect.Throws(typeof(ArgumentNullException), () => Type.GetTypeHandle(nullString));
    Expect.Throws(typeof(ArgumentNullException), () => Type.GetTypeHandle(nullStringAsObject));
    Assert.AreEqual(typeof(string), Type.GetTypeFromHandle(Type.GetTypeHandle(stringAsObject)));
    Assert.AreEqual(typeof(string), stringAsObject.GetType());

    // resolved at compile time
    Assert.AreEqual(Answer.String, this.GetAnswer(nullString));
    Assert.AreEqual(Answer.Object, this.GetAnswer(nullStringAsObject));
    Assert.AreEqual(Answer.Object, this.GetAnswer(stringAsObject));
    Assert.AreEqual(Answer.Object, this.GetAnswer((object)null));
    Assert.AreEqual(Answer.String, this.GetAnswer((string)null));
    Assert.AreEqual(Answer.String, this.GetAnswer(null));
}

// Uncommenting the following method overload
// makes the last statement in the test case ambiguous to the compiler
// private Answer GetAnswer(FileInfo f) { return Answer.FileInfo; }

참조 URL : https://stackoverflow.com/questions/8204578/what-is-the-type-of-null-literal

반응형