Nullable 의 복싱/언복싱 동작은 어떻게 가능합니까?
오늘 아침에 갑자기 머리가 긁히는 일이 생겼습니다.
모든 유형의 변수Nullable<T>
에 할당할 수 있습니다.null
예를 들어:
int? i = null;
처음에 저는 어떻게든 암시적 변환을 정의하지 않고 어떻게 이것이 가능한지 볼 수 없었습니다.object
로.Nullable<T>
:
public static implicit operator Nullable<T>(object box);
그러나 위 연산자는 분명히 존재하지 않습니다. 마치 존재했던 것처럼 다음 연산자도 합법적이어야 합니다. 적어도 컴파일 시간에는 그렇지 않습니다.
int? i = new object();
그때 깨달았어요 아마도Nullable<T>
type은 다음과 같이 인스턴스화할 수 없는 임의의 참조 유형으로 암시적 변환을 정의할 수 있습니다.
public abstract class DummyBox
{
private DummyBox()
{ }
}
public struct Nullable<T> where T : struct
{
public static implicit operator Nullable<T>(DummyBox box)
{
if (box == null)
{
return new Nullable<T>();
}
// This should never be possible, as a DummyBox cannot be instantiated.
throw new InvalidCastException();
}
}
하지만, 이것은 다음에 나에게 무슨 일이 일어났는지 설명하지 못합니다: 만약에.HasValue
재산은false
어떤 경우에도Nullable<T>
값을 입력하면 해당 값이 다음과 같이 상자에 표시됩니다.null
:
int? i = new int?();
object x = i; // Now x is null.
게다가, 만약에HasValue
이라true
그러면 값이 상자로 표시됩니다.T
가 아니라T?
:
int? i = 5;
object x = i; // Now x is a boxed int, NOT a boxed Nullable<int>.
하지만 이것은 다음과 같은 경우의 사용자 정의 암묵적 변환이 있다는 것을 의미하는 것으로 보입니다.Nullable<T>
로.object
:
public static implicit operator object(Nullable<T> value);
이것은 분명히 사실이 아닙니다.object
는 모든 유형에 대한 기본 클래스이며, 기본 유형에서 사용자 정의 암시적 변환은 불법입니다.
는 것 같습니다.object x = i;
박스에 넣어주세요.i
다른 가치 유형과 마찬가지로, 그래서.x.GetType()
와 동일한 결과를 산출할 것입니다.typeof(int?)
(던지기 보다는)NullReferenceException
).
그래서 저는 주변을 좀 둘러보았고, 물론, 이 행동은 특정한 것으로 밝혀졌습니다.Nullable<T>
C# 및 VB.NET 사양 모두에서 특별히 정의되며 사용자 정의에서는 재현할 수 없는 유형struct
(C#) 또는Structure
(VB.NET).
제가 아직도 혼란스러운 이유가 여기 있습니다.
이러한 특정 복싱 및 언복싱 동작은 손으로 구현하는 것이 불가능한 것으로 보입니다.C#과 VB.NET 둘 다 특별한 치료를 제공하기 때문에 작동합니다.Nullable<T>
유형.
이론적으로 다른 CLI 기반 언어가 존재할 수 있지 않습니까?
Nullable<T>
이런 특별한 대우를 받지 않았습니까?그리고 그것은.Nullable<T>
따라서 유형은 다른 언어에서 다른 행동을 나타냅니까?C# 및 VB.NET은 어떻게 이 동작을 수행합니까?CLR에서 지원합니까? (즉, CLR은 C# 및 VB.NET 자체가 금지하더라도 유형이 박스 방식을 "오버라이드"할 수 있습니까?)
(C# 또는 VB.NET에서) a를 상자에 넣는 것이 가능합니까?
Nullable<T>
~하듯이object
?
두 가지 일이 진행되고 있습니다.
컴파일러는 "null"을 null 참조가 아닌 null 값으로 처리합니다.변환해야 하는 유형에 대한 null 값입니다.의 경우Nullable<T>
입니다.HasValue
밭/밭그래서 만약 당신이 유형의 변수를 가지고 있다면.int?
그 변 값 다 음 같 가 을 있 꽤 니 습 다 이 성 능 과 수 의 이 다 ▁for ▁it ▁to ▁possible ▁quite 니 ▁variable s 있 ▁of 습 ▁be ' ▁the ▁value 꽤 ▁thatnull
당신은 단지 무엇에 대한 당신의 이해를 바꿀 필요가 있습니다.null
약간의 의미가 있습니다.
복싱 무효형은 CLR 자체에 의해 특별 대우를 받습니다.이는 두 번째 예와 관련이 있습니다.
int? i = new int?();
object x = i;
컴파일러는 null 가능한 형식 값을 null 불가능한 형식 값과 다르게 상자에 넣습니다.null이이 아닌 을 상자에 넣는 null이 null이 아닌 을 사용할 수 없습니다. 따라서int?
값이 5인 경우와 동일한 방식으로 상자에 들어갑니다.int
값 5 - "가용성"이 손실됩니다.그러나 null 가능한 유형의 null 값은 개체를 전혀 생성하지 않고 null 참조로만 상자에 표시됩니다.
이는 CLR v2 사이클 후반에 커뮤니티의 요청에 따라 도입되었습니다.
이는 "상자에 들어 있는 nullable-value-type 값"과 같은 것이 없음을 의미합니다.
당이옳습다니신다니.Nullable<T>
와 C. VB 및 C# 모 에 서 러 로 부 받 니 습 다 를 처 터 리 특 한 수 일따라서:
- 한 대소문자를 사용해야 . 언컴파케필요다이니합가스네특수.
Nullable<T>
. - 는 컴일러는다사리팩다니합터용을의 을 .
Nullable<T>
연산자는 단지 통사적인 설탕일 뿐입니다. - 아는 바 없는데요.
저는 저 자신에게 같은 질문을 하고 있었고 또한 저는 암시적인 연산자가 있을 것이라고 기대했습니다.Nullable<T>
.net Null 가능 소스 코드에서 IL 코드가 무엇인지 살펴봤습니다.int? a = null;
현장에서 무슨 일이 일어나고 있는지 이해하는 것:
c# 코드:
int? a = null;
int? a2 = new int?();
object a3 = null;
int? b = 5;
int? b2 = new int?(5);
IL 코드(LINQPad 5로 생성):
IL_0000: nop
IL_0001: ldloca.s 00 // a
IL_0003: initobj System.Nullable<System.Int32>
IL_0009: ldloca.s 01 // a2
IL_000B: initobj System.Nullable<System.Int32>
IL_0011: ldnull
IL_0012: stloc.2 // a3
IL_0013: ldloca.s 03 // b
IL_0015: ldc.i4.5
IL_0016: call System.Nullable<System.Int32>..ctor
IL_001B: ldloca.s 04 // b2
IL_001D: ldc.i4.5
IL_001E: call System.Nullable<System.Int32>..ctor
IL_0023: ret
컴파일러가 변경되는 것을 볼 수 있습니다.int? a = null
와 비슷한 정도로int? a = new int?()
은 상는당다른히와 상당히 .object a3 = null
따라서 Nullables에는 특별한 컴파일러 처리가 있습니다.
언급URL : https://stackoverflow.com/questions/3775582/how-is-the-boxing-unboxing-behavior-of-nullablet-possible
'programing' 카테고리의 다른 글
GET 요청 대신 OPTIONS 요청을 받는 이유는 무엇입니까? (0) | 2023.05.28 |
---|---|
Xcode 8 콘솔 쓰레기? (0) | 2023.05.28 |
이클립스:log4j.xml의 log4j.dtd 참조 (0) | 2023.05.28 |
UIV 시각 효과 보기를 사용하여 이미지를 흐리게 하는 방법은 무엇을 참조하십시오. (0) | 2023.05.28 |
ON CONCLIVE 절에서 multipleconflict_target 사용 (0) | 2023.05.28 |