about
07/05/2024
CsBites - Introduction
C# Bites Code C# Bits Hello World

C# Bites - Introduction

What are Bites?, Why C#?

Welcome to C# Bites! These Bites are a thread of linked webpages that focus on the C# programming language. You navigate using "Next" and "Prev" buttons on the top and bottom menus, or the "Pages" button on the top and bottom right. Each Bite provides an introduction to, and discusses the ideas behind, some aspect of the C# language. The Pages buttons show things we will be covering in this sequence.

1.0 Why C#?

C# was created, and development has been supported, by Microsoft starting in 2002. Recently the C# ecosystem: compiler, libraries, and development tools, has been ported to Linux and macOS. Many Commercial and Industrial Organizations are Using C#:
As of April 2021, there were more than six million C# developers.

Things you need to know:


Figure 1. C# Type Structure
Figure 2. CIL Processing
  • The C# programming language is designed to support creation and management of user-defined reference types that reside in a managed heap. Managed languages, like C# and Java, use managed handles to access instances on the heap.
  • C# classes compose managed handles to their heap objects, so an assignment results in copying the source handle to represent the target of that operation. After assignment there are two handles pointing to the same instance.
  • The language also supports creation of user-defined value types that reside in stack memory. Value types are primitives and structs with only value type members. Assignment results in copying the entire value instance, resulting in an independent value.
  • The C# language compiles to a bite code representation called Common Intermediate Language (CIL) which is designed to run on a stack-based virtual machine, hosted in the process created for a C# program's execution.
  • CIL is Just-In-Time (jit) translated to native code that implements the execution stack and pushes, operates on, and pops data from the stack, often to and from machine registers.
  • The C# compiler emits CIL statements that depend only on the stack-based virtual machine structure. It does not depend on the various types of hardware targets. That is handled by the virtual machine, implemented for each type of target platform.
  • This requires two phases of translation:
    1. Program source to CIL by the C# compiler.
    2. CIL to native code by the virtual machine when CIL is loaded to run.
    The second phase introduces run-time latency when CIL is compiled. That happens only once since generated native code is cached.
  • Because C# manages all references with a garbage collector, developers do not need to defend against pointer errors, but that management has a significant impact on code execution latency and throughput. Managed references do not own their referred instances. The garbage collector handles all resource allocation and disposal.
  • Managed code is wrapped in a Common Language Runtime (CLR) that provides garbage collection, exception handling, CIL code verification and translation, and thread management.
  • Modern versions of the CLR are now referred to as the .Net runtime.

C# Highs

  1. Memory Safety
    All data is owned by the Common Language Runtime (CLR) garbage collector. In safe C# developer code only has access to managed pointers that are tracked by the garbage collector and disposed when there are no more references.
  2. Error Handling
    The CLR provides strong management of exceptions. The language also has syntax for managing elements that can be null. That partitioning of code has the compiler check for problematic code.
  3. Reflection
    .Net provides reflection facilities to query for an instance's type, methods, and fields at run-time. This is a powerful mechanism for building flexible systems that are easy to maintain and extend.
  4. Object Model
    C#'s object model is rooted in the type Object that provides all instances facilities for reflection with System.Object.GetType(), comparison with ReferenceEquals(Object) and conversion with ToString().
  5. Productivity
    C# programs tend to work correctly as soon as they compile. There are no memory bugs to find and fix. That combined with effective tools and extensive libraries help to make development productive.
  6. Effective Tool Chain
    The Visual Studio Integrated Development Environment (IDE) tool creates, manages dependencies, builds, and executes programs and library tests. It has many project templates that supply boiler-plate configuration so the developer doesn't need to.
    Visual Studio Code is a lightweight code editor with management plugins for compiling, execution, and debugging. It runs on Windows, Linux, and macOS, supporting code development on each of those platforms with nearly the same workflow process.
    The .Net Environment provides deep integration with the Windows platform and there are many development plugins for Graphical User Interface (GUI) development, database management, and networking.
  7. Delegates
    C# delegates make event handling a much simpler process that it would be otherwise.
  8. Properties
    C# properties provide encapsulation of data that uses, for access, the simple syntax of unencapsulated public members.

C# Lows

  1. Performance C# compiles to CIL which is jitted causing latency for the first run of changed code. The CLR garbage collector requires a significant amount of processing to track references to all of a program's reference type instances.
    Garbage collection runs in three tiers, deallocating instances of no longer used reference types. That can cause unexpected latencies during program operation.
  2. Three Categories of Type Behavior
    1. Strictly typed Reference types have assignments that result in sharing of instances between source and destination, e.g., one instance, not two independent instances.
    2. Strictly typed Value types have assignment semantics that result in two independent instances.
    3. Duck typed Dynamic types are references that inherit the types of their data and can be rebound at runtime.
      Runtime exceptions happen frequently when methods are called on dynamic references to data types that do not support the called method.
    The fundamental differences in semantics of these type categories makes program development and review more difficult.

Getting Started

  • C# Tool Chain:

    For any environment, download .Net tools. This gives you "dotnet Command Line Interface (CLI), C# compiler, CLR, ildasm - a disassembler to CLI, and other tools. This is all the tooling you need to start.
  • Visual Studio Code

    C# doesn't come with an IDE, but VS Code gives you a text editor with a terminal pane, from which you enter dotnet commands build, run, clean, and more. You will want to install the VS Code plugin "C#" which gives you some syntax highlighting and code completion. You will find, in the left border, an icon for selecting plugins. Just use the search box to find the C# pluggins you need. The VS Code model expects you to use JSON files to configure build and debug launchers. I have found that occasionally hard to use, and often requires more effort to configure than I am willing to spend on this tool. Working in the code editor and launching dotnet commands in the terminal works well for me. For Windows, I use the powershell (PS) terminal, but that can be replaced with the Developer Cmd prompt. On linux the default bash terminal works well.

References:

Reference Description
C# Tutorial - w3shools Simple tutorial with guided exercises
C# programming language - Wikipedia Summary of the language with lots of reference links
Understanding CIL - CodeProject Clear introduction to the Common Intermediate Language
Common Intermediate Language - Wikipedia Quick summary
List of CIL Instructions - Wikipedia Extensive list, useful for reference
  Next Prev Pages Sections About Keys