class Box
{
public void Open()
{
System.Console.WriteLine("Box opened");
}
}
class Program
{
static void Main()
{
// The program begins here.// ... Create a new Box and call Open on it.
Box box = new Box();
box.Open();
}
}Box opened
Nested class. Here we see a nested class instance. Nested classes refer to class declarations that occur in other class declarations.
Info Class B is enclosed inside the declaration of class A. It is thus a nested class.
And Because it has a public accessibility modifier, class B can be accessed in places other than class A's scope.
Here We create an instance of A and an instance of A.B. The instance of A does not contain an instance of B.
class A
{
public int _v1;
public class B
{
public int _v2;
}
}
class Program
{
static void Main()
{
A a = new A();
a._v1++;
A.B ab = new A.B();
ab._v2++;
}
}
Field ordering. In a class, does the ordering of fields matter? In older languages, sometimes it does—bytes must be next to each other to fit into 4-byte words.
Here I test how effectively the C# compiler "packs" fields. I measure memory usage of classes. I break down all the allocations.
Info In class "A," the byte and int fields are not grouped by their type. But in class "B," the bytes and ints are grouped by type.
Detail The Main method allocates 100,000 instances of both classes. The array memory usage is measured.
using System;
class A
{
byte b1;
int i1;
byte b2;
int i2;
byte b3;
int i3;
byte b4;
int i4;
}
class B
{
byte b1;
byte b2;
byte b3;
byte b4;
int i1;
int i2;
int i3;
int i4;
}
class Program
{
static void Main()
{
// ... Measure class "A".
long m1 = GC.GetTotalMemory(true);
A[] ar1 = new A[100000];
for (int i = 0; i < ar1.Length; i++)
{
ar1[i] = new A();
}
long m2 = GC.GetTotalMemory(true);
Console.WriteLine(m2 - m1);
Console.WriteLine((m2 - m1) / 100000);
ar1[0] = null;
ar1 = null;
// ... Measure class "B".
long m3 = GC.GetTotalMemory(true);
B[] ar2 = new B[100000];
for (int i = 0; i < ar2.Length; i++)
{
ar2[i] = new B();
}
long m4 = GC.GetTotalMemory(true);
Console.WriteLine(m4 - m3);
Console.WriteLine((m4 - m3) / 100000);
ar2[0] = null;
ar2 = null;
}
}3200016 [bytes total, A]
32 [bytes per element, A]
3200016 [bytes total, B]
32 [bytes per element, B]
Field, results. Ordering did not matter for memory usage. So you can place your fields in any order you like in the source code file—it makes no difference.
Detail The class reference (within the arrays) accounted for 4 bytes per object. An empty class (with no fields) required 12 bytes.
However A class with just one int field also required 12 bytes. This is the smallest class size possible.
Info I included the 4 bytes from the first int into the minimum class size. Then I added all the remaining fields.
And The four byte fields occupied only four bytes. They were effectively packed together in memory.
Summary. With classes, we create instances of custom types. This gives a great power to model data. C# is a language based around classes, and they help keep it usable.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Dec 22, 2023 (simplify).