Type Declaration

Generally speaking, if you take a look at languages like C, C++ and C#, you’ll notice this pattern:

  • A C program is a collection of functions and data types
  • A C++ program is a collection of functions and classes
  • The core essence of a C# program, however, is a set of type declarations

The source code for any C# executable (EXE) or dynamic link library (DLL) is made up of one or more type declarations.

DLL files have no Main entry point, while an executable (EXE) must contain at least one class with a method named Main that acts as the program’s entry point.

Large software projects can contain thousands of distinct types (such as classes) across their source files. These projects are usually developed by multiple programmers, each responsible for separate modules, which makes duplicate type names almost inevitable. How do we resolve naming conflicts in such cases? This is where the concept we covered earlier—namespaces—comes into play.

A namespace groups related type declarations into organized categories and assigns a unified identifier to this group. Since every program is fundamentally a collection of interconnected type declarations, developers almost always create custom namespaces to encapsulate all their project’s types inside them.

Simply put, a namespace adds a group identifier to a set of classes. Any code outside this group must reference the namespace prefix to access those classes.

Think of it like students sharing identical full names in the same classroom. Teachers and classmates can’t tell them apart by name alone, so extra labels are added to distinguish them—for example, Tom from Group A and Tom from Group B. The “Group A” and “Group B” labels work exactly like namespaces here.

The code snippet below demonstrates a program with three separate type declarations, all defined within a namespace called MyProgram.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloDemo // Declare a namespace
{

    class A                  // Declare Type A (Class)
    {
        void Fun1() // Function
        {
            // Program logic
        }
    }

    class B                  // Declare Type B (Class)
    {
        void Fun1() // Function
        {
            // Program logic
        }
    }

    class C                  // Declare Type C (Class)
    {
        static void Main(string[] args) // Main program entry point
        {
            double pi = 3.14;
            string webSite = "foxdevelop.com";
            Console.WriteLine($"The Pi is {pi} and the website is {webSite}.");
        }
    }

}
Code language: JavaScript (javascript)

We’ll dive deeper into namespaces in later lessons.

Types Act As Templates

Given that C# programs are fundamentally collections of type declarations, mastering C# boils down to learning how to define and utilize types. First, we need to clarify one key concept:

What exactly is a Type?

You can visualize a type as a template for building data structures. It isn’t a tangible data structure itself, but it defines all the properties that objects instantiated from this template will carry.

A type is merely a blueprint that occupies no memory on its own. Memory allocation and data storage only occur once you create an instance from the type template.

A type is a blueprint used to generate concrete object instances. It’s analogous to architectural house blueprints—you can build countless individual houses following one single blueprint design.

Every type is defined by three core components:

  1. Name
  2. Data structure for storing member values
  3. Supported behaviors and constraints

In C#, everything is a type—even the built-in primitive data types.

Two common built-in types are shown below: short and int.

Their structural breakdown is as follows:

short Typeint Type
Name: shortName: int
Structure: Occupies 2 bytesStructure: Occupies 4 bytes
Behavior: 16-bit integerBehavior: 32-bit integer
  • Name: Unique identifier for the type (int/string/custom class names)
  • Storage Structure: Defines memory footprint and field layout (e.g. short is fixed at 2 bytes)
  • Behavior Constraints: Specifies valid operations, value ranges and native methods (e.g. int supports arithmetic operations, with a value range of -2^31 ~ 2^31-1)

Instantiation

Use the new keyword alongside a type template to create a functional, usable data object

Object = Instance

Take the int and short types above as an example: we can generate instances from these base types. In the sample below, pi, age and nums are all instances created from the double, int and short built-in types respectively.

namespace HelloDemo 
{

    class Program
    {
        static void Main(string[] args)
        {
            double pi = 3.14;
            int age = 12;
            short nums = 23;
        }
    }

}Code language: JavaScript (javascript)

In C#, every single variable and data value within a program is an instance of some type—there is no such thing as untyped data.

Refer back to the earlier sample for reference

The sample class C serves as the executable’s entry class and meets all EXE requirements:

  • It is a custom type contained within the MyProgram namespace
  • It contains a static void Main method that acts as the application startup entry point

C# Has More Types Than Just Classes

All Declarable Types in C#: Class, Struct, Interface, Enum, Delegate, Record

BCL (Base Class Library): The standard built-in .NET class library that supplies system predefined types such as int, short, string and List<T>, which developers can instantiate directly for use.

Type Declaration

Leave a Reply

Your email address will not be published. Required fields are marked *