In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces "what is the principle of C# nullable type". In daily operation, I believe that many people have doubts about what the principle of C# nullable type is. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the question of "what is the principle of C# nullable type?" Next, please follow the editor to study!
For the convenience of demonstration, I will define an int? Type to receive both non-null and null cases.
Static void Main (string [] args)
{
Int? Num1 = 10
Int? Num2 = null
Console.WriteLine ("execution is over!")
Console.ReadLine ()
}
1. Dig IL code
It is easy to dig the IL code, just use the ILSPY gadget. The compiled IL code is as follows:
.method private hidebysig static
Void Main (
String [] args
) cil managed
{
/ / Method begins at RVA 0x2048
/ / Code size 36 (0x24)
.maxstack 2
.entrypoint
.locals init (
[0] valuetype [mscorlib] system. Nullable`1 num1
[1] valuetype [mscorlib] system. Nullable`1 num2
)
IL_0000: nop
IL_0001: ldloca.s 0
IL_0003: ldc.i4.s 10
IL_0005: call instance void valuetype [mscorlib] system. Nullable`1:: .ctor (! 0)
IL_000a: ldloca.s 1
IL_000c: initobj valuetype [mscorlib] system. Nullable`1
IL_0012: ldstr "execution is over!"
IL_0017: call void [mscorlib] System.Console::WriteLine (string)
IL_001c: nop
IL_001d: call string [mscorlib] System.Console::ReadLine ()
IL_0022: pop
IL_0023: ret
} / / end of method Program::Main
This IL code is still very easy to understand, much simpler than assembly (┬ _ ┬), you can see int? It's System.Nullable, and you can see from the valuetype tag that it's a value type, so turning the above code into C # code is like this.
{
Static void Main (string [] args)
{
/ / int? Num1 = 10
/ / int? Num2 = null
Nullable num3 = new Nullable (10)
Nullable num4 = new Nullable ()
Console.WriteLine ("execution is over!")
Console.ReadLine ()
}
It's very simple, so how to output num3 and num4? It would be nice to just Console.WriteLine.
You must have a question here: why does num3 output 10 and num4 outputs nothing? Haha, this is because Nullable's ToString () has been rewritten. Let's take a look at how ToString is rewritten. The code is as follows:
Public struct Nullable where T: struct
{
Private bool hasValue
Internal T value
[NonVersionable]
[_ _ DynamicallyInvokable]
Public Nullable (T value)
{
This.value = value
HasValue = true
}
[_ _ DynamicallyInvokable]
Public override string ToString ()
{
If (! hasValue)
{
Return ""
}
Return value.ToString ()
}
}
You can see that the ToString method either returns an empty string or the value you stuffed in the constructor. This is as simple as this, just dig up the IL code here.
two。 Dig machine code
To see the machine code of num1 and num2, you can actually look at the memory layout of Nullable. Here I use windbg, or use! clrstack-l to view the thread stack.
Int? Num1 = 10
Int? Num2 = null
0RV 007 > ~ 0s
Ntdllqualified ZwReadFilekeeper 0x14:
00007ffc`ec11aa64 c3 ret
0VOU 000 >! clrstack-l
OS Thread Id: 0x5364 (0)
Child SP IP Call Site
ConsoleApp4.Program.Main (System.String []) [C:\ dream\ Csharp\ ConsoleApp1\ ConsoleApp4\ Program.cs @ 21]
LOCALS:
0x00000018a9dfeaf8 = 0x0000000a00000001
0x00000018a9dfeaf0 = 0x0000000000000000
00000018a9dfed08 00007ffcd5b66c93 [GCFrame: 00000018a9dfed08]
As you can see from LOCALS, the contents stored on the thread stack of num1 and num2 are 0x0000000a00000001 and 0x0000000000000000, respectively, but this value is also very strange, one is 1 and the other is 0. We use the dd command to dump the address.
0RV 000 > dd 0x00000018a9dfeaf8
00000018`a9dfeaf8 00000001 00000a a9dfec08 00000018
0RV 000 > dd 0x00000018a9dfeaf0
00000018`a9dfeaf0 00000000 00000000 00000001 00000a
There is a hexadecimal value of 0000000a in the memory area of num1, which is decimal 10, so what is the first 00000001? Don't forget, int? It's grammar candy. You're looking at Nullable now.
You can see clearly that there are two value type fields in this structure, and naturally 00000001 is hasValue=true. Num2 is also easy to understand, the two default values are two zeros. 00000000 00000000 .
Three: there is an unexpected discovery
1. Int? Takes up more memory than int
If you have a large amount of data in memory, you should be careful, int? It takes 4 bytes more than int on x64, that is, twice as much, regardless of thread stack or managed heap.
two。 Why does bool occupy 4 bytes of space?
Demo on thread stack
Some people must be wondering, isn't bool just a byte in C #? How do you say 4 bytes? If you ask me, I can only say that from the point of view of windbg, the thread stack of x64 system is based on 4 bytes. If you don't believe me, I will define the value types of different fields in the code. Just look at the distribution on the thread stack and speak with the facts.
Byte b1 = byte.MaxValue
Byte b2 = byte.MaxValue
Short b3 = short.MaxValue
Short b4 = short.MaxValue
Int b5 = int.MaxValue
Int b6 = int.MaxValue
0VOU 000 >! clrstack-l
OS Thread Id: 0xa98 (0)
ConsoleApp4.Program.Main (System.String []) [C:\ dream\ Csharp\ ConsoleApp1\ ConsoleApp4\ Program.cs @ 25]
LOCALS:
0x000000a8395fedbc = 0x00000000000000ff
0x000000a8395fedb8 = 0x00000000000000ff
0x000000a8395fedb4 = 0x0000000000007fff
0x000000a8395fedb0 = 0x0000000000007fff
0x000000a8395fedac = 0x000000007fffffff
0x000000a8395feda8 = 0x000000007fffffff
Then dump the smallest address, 0x000000a8395feda8.
0RV 000 > dd 0x000000a8395feda8
000000a8`395feda8 7fffffff 7fffffff 00007fff 00007fff
000000a8`395fedb8 000000ff 000000ff 395feec8 000000a8
000000a8`395fedc8 395fefc8 000000a8 395fee00 000000a8
000000a8`395fedd8 d5b66c93 00007ffc 98e72d30 000001ee
000000a8`395 fede8 76504140 00007ffc 00000000 00000000
000000a8`395fedf8 00000000 00007ffc 395feef0 000000a8
000000a8`395 08 971d0b20 000001ee 00000000 00000000
000000a8`395 18 d5b66b79 00007ffc 00000000 00000000
By comparison, you can see that the above 7fffffff, 00007fff MaxValue 000000ff is the corresponding int,short,byte MaxValue, which takes up 4 bytes of space, all right?
Managed heap demonstration
Var arr1 = new int [] {10}
Var arr2 = new int? [] {14}
0VOU 000 >! clrstack-l
OS Thread Id: 0x23f8 (0)
000000859a1fec60 00007ffc76630967 ConsoleApp4.Program.Main (System.String []) [C:\ dream\ Csharp\ ConsoleApp1\ ConsoleApp4\ Program.cs @ 32]
LOCALS:
0x000000859a1feca0 = 0x000002773cb32d70
0x000000859a1fec98 = 0x000002773cb32d90
000000859a1feeb8 00007ffcd5b66c93 [GCFrame: 000000859a1feeb8]
0VOU 000 >! do 0x000002773cb32d70
Name: System.Int32 []
MethodTable: 00007ffcd2d58538
EEClass: 00007ffcd2ec5918
Size: 28 (0x1c) bytes
Array: Rank 1, Number of elements 1, Type Int32 (Print Array)
Fields:
None
0VOU 000 >! do 0x000002773cb32d90
Name: system. Nullable`1 [[System.Int32, mscorlib]] []
MethodTable: 00007ffcd3fb2058
EEClass: 00007ffcd30221a0
Size: 32 (0x20) bytes
Array: Rank 1, Number of elements 1, Type VALUETYPE (Print Array)
Fields:
None
0VOU 000 >! objsize 0x000002773cb32d70
Sizeof (000002773cb32d70) = 32 (0x20) bytes (System.Int32 [])
0VOU 000 >! objsize 0x000002773cb32d90
Sizeof (000002773cb32d90) = 32 (0x20) bytes (system. Nullable`1 [[System.Int32, mscorlib]] [])
As you can see, one is 28byte, the other is 32byte, and the extra one is that hasValue, ha. One thing to note is that 32byte is typed out with! objsize, this is because 28byte is changed into 32byte by 8 alignment, and then I dump the two value types, as shown in the following figure:
At this point, the study on "what is the principle of C# nullable type" is over. I hope to be able to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.