C# .NET Programming Language

.C# Introduction
Data Types | Access Modifiers | Method Modifiers | Parameters | Properties | Strings |
DateTime | Interfaces | Naming | Shortcuts

"The original C# mascot was named Andy, after C#'s principal designer Anders Hejlsberg. Andy the mascot retired in 2004."

.Andy C# Mascot

The C# programming language has a long lineage with influences from many programming languages: ALGOL, CPL, BCPL, B, C, IPL, Lisp, Simula, Modula, Pascal, Logo, Smalltalk, C++, Objective-C, C++, Java. This is not an all-inclusive list, but it gives a view of how the foundations of C# have evolved over decades.

C# has added significant features since it's first release in 2002 as part of the .NET framework. Lambda expressions, extension methods, closures, LINQ extensions, dynamic binding, asynchronous methods, and other features were added in various releases. Today C# version 5.0 is a primary language in Microsoft's .NET framework for software development. As a .NET language, C# runs on a virtual machine (CLR) that manages memory, object references, and performs Just-In-Time (JIT) compiling of the intermediate code created by the C# compiler. C# has a unified type system where all the types (including primitive types) inherit from a single root object type. This allows types to share common operations and their values can be stored, transported, and operated upon in a consistent manner.The C# language specification is defined in the ECMA-334 Standard, however Microsoft retains architectural control of the language.

Some significant aspects of C# include:

  1. C# has a unified type system with all types ultimately inherited from object. This is unlike Java and C++ where the primitive types do not interoperate with objects.

  2. The C# type system contains two type categories:
    1. Value Types - directly contain data, stored in the stack, null values not allowed. (Primitives, Enum, Struct)
    2. Reference Types - contains references to data, stored in the heap, may contain null values. (Class, Interface, Delegate, Array)
  3. C# provides built-in "interfaces" which provide for standard behaviors (method names) to be used throughout the .NET base class library. C# also allows for the development of custom interfaces.

  4. C# contains "delegates" which are basically object-oriented function pointers. Delegates have many uses, including providing the foundation for events.

  5. C# contains "generics" which were heavily used in creating predefined collections. C# also allows the development of custom generic classes, struct, delegates, and methods. Generics provide for type safety and eliminates the overhead of "boxing" and "unboxing" value types to/from reference types.

  6. C# contains "attributes" which allow metadata to be associated with types and members. Reflection allows the metadata to be retrieved at runtime.

  7. Classes can contain static or instance members. Class members include: constants, fields, methods, properties, indexers, events, operators, constructors, and destructors.

  8. C# can only inherit from one base class (unlike C++ which supports multiple class inheritance). However C# can implement zero or more interfaces. C# only supports class inheritance; inheritance from structs is not supported.

  9. C# requires code segments which use pointers to be labeled as "unsafe". C# contains capabilities such that the routine use of pointers is not required.


C# Versions

Anders Hejlsberg is C#'s principal designer and lead architect at Microsoft. Hejlsberg was the original author of Turbo Pascal and the chief architect of Delphi. Hejlsberg has a power point presentation at the ECMA site called Introduction to C# by Anders Hejlsberg. Hejlsberg has been influential in the development of C# through its various releases.

Version Date .NET Framework Visual Studio Enhancements
C# 1 2002 .NET 1 Visual Studio .NET 2002
C# 1.2 2003 .NET 1.1 Visual Studio .NET 2003
C# 2 2005 .NET 2 Visual Studio 2005 Partial Classes, Generics, Nullable, Anonymous
C# 3 2007 .NET 3.5 Visual Studio 2008 Lambda, Partial Methods, Var, Linq, Initializers, Extensions, Auto Props
C# 4 2010 .NET 4 Visual Studio 2010 Dynamics, Optional Args, Covariance
C# 5 2012 .NET 4.5 Visual Studio 2012 Async, Caller Attr



C# Versions


Variable and Data Types



C# supports two variable types in managed code:

  1. Value types - built-in primitive data types, such as char, int, and float, as well as user-defined types declared with struct. Stores a copy of the value; the value is allocated in the stack.

  2. Reference types - Objects, Strings, and other complex data types that are constructed from the primitive types. Stores a reference address to the value; the value is allocated in the heap.

Note: Pointer types are only available in "unsafe" code. Used to access memory directly, for high performance applications.

Implicit data conversions are allowed if precision is increased. If precision is decreased an explicit cast is required.

Type Alias Notes
Object (Reference) object, string Strings are immutable. (StringBuilder)
Signed sbyte, short, int, long int= System.Int32
Unsigned byte, ushort, uint, ulong byte = 8, short=16, int = 32, long= 64
Character char char = 16 (Unicode)
Floating-point float, double, decimal float=32, double = 64, decimal = 128 (precise fractional)
Logical bool bool = 8 (True/False)
Enumeration enum Int32 used by default.
Reference DateTime An instance in time.
Reference TimeSpan A time interval.



C# Data Types





Top


Access Modifiers



Types and type members use access modifiers to specify an accessibility level. Access modifiers are specified in the definition and control whether the type or membercan be used from other code in your assembly or from other assemblies. Access modifiers include:

  • public - The type or member can be accessed by any other code in the same assembly or another assembly that references it.

  • private - The type or member can be accessed only by code in the same class or struct.

  • protected - The type or member can be accessed only by code in the same class or struct, or in a class that is derived from that class.

  • internal - The type or member can be accessed by any code in the same assembly, but not from another assembly.

  • protected internal- The type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class in another assembly. Access from another assembly must take place within a class declaration that derives from the class in which the protected internal element is declared, and it must take place through an instance of the derived class type.



Top


Method Modifiers



Modifiers are used to modify declarations of types and type members.

  • abstract - Indicates that a class is intended only to be a base class of other classes.

  • extern - Indicates that the method is implemented externally.

  • override - Provides a new implementation of a virtual member inherited from a base class.

  • partial - Defines partial classes, structs and methods throughout the same assembly

  • sealed - Specifies that a class cannot be inherited.

  • static - Declares a member that belongs to the type itself instead of to a specific object. If calling a static method, you must use the class name, NOT the instance name (As no instance may even exist). You can create static constructors to initialize the state of a static values. However if you get an exception while setting a static value, the value will be unusable in that process.

  • virtual - Declares a method or an accessor whose implementation can be changed by an overriding member in a derived class.

  • volatile - Indicates that a field can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread.

Top


Parameters



Arguments can be passed to parameters either by value (by Default) or by reference (by using ref and out keywords). Passing by reference allows methods to change the value of the parameters and have that change persist back to the calling environment. C# supports positional parameters, named parameters, and optional parameters.

Parameter Passing Example
.Passing Parameters by Value and by Reference



Main for Passing Parameters by Value and by Reference

using System;
using AddClass;

namespace ParameterPassingExample
{
    class Program
    {
        static void Main()
        {
            Add adder = new Add();

            double myParm = 5;

            // Pass by Value
            Console.WriteLine("The result is: {0}", adder.addTwiceByValue(myParm));
            Console.WriteLine("After call myParm is: {0}\n", myParm);

            // Pass by Reference
            Console.WriteLine("The result is: {0}", adder.addTwiceByRef(ref myParm));
            Console.WriteLine("After call myParm is: {0}\n", myParm);
        }
    }
}

Add Class for Passing Parameters by Value and by Reference

namespace AddClass
{
    class Add
    {
        public double addTwiceByValue(double a)
        {
            a *= 2;
            return a;
        }

        public double addTwiceByRef(ref double a)
        {
            a *= 2;
            return a;
        }
    }
}


Pass Multiple Parameters using params Keyword

Use the params keyword to pass multiple arguments as method parameters, as shown below. If additional parameters are used, then params needs to be the last in the parameter list.

.Passing Multiple Parameters



Main for Passing Multiple Parameters

using System;
using AddClass;

namespace ParameterPassingExample
{
    class Program
    {
        static void Main()
        {
            Add adder = new Add();

            Console.WriteLine("The sum is: {0}\n", adder.AddThemUp(2.75, 2.25, 50.50));
        }
    }
}

Add Class for Passing Multiple Parameters

namespace AddClass
{
    class Add
    {
        public double AddThemUp(params double[] theArray)
        {
            double sum = 0.0;
            foreach (double theNumber in theArray)
                sum += theNumber;
            return sum;
        }
    }
}

Top


Properties

  • A property is a member that provides encapsulation by controlling access to an object's data with a flexible mechanism to read, write, or compute the value of a private field. Properties can be used as if they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily and still helps promote the safety and flexibility of methods.

  • The accessor of a property contains the executable statements associated with getting (reading or computing) or setting (writing) the property. The accessor declarations can contain a get accessor, a set accessor, or both. The declarations take the following forms:

    set {accessor-body}
    get {accessor-body}
    


  • Instance Property

    An instance property is associated with a given instance of a class, and that instance can be accessed as this in the accessors of that property.

    Below is an Employee class that has a private field for the name. The class also contains a Name property that allows the private field value to be read and updated outside the class scope (after the class has been instantiated).

    Employee.cs

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

    namespace ConsoleApplication1
    {
        class Employee
        {
            private string name; // the name field
            public string Name   // The Name property
            {
               get
               {
                  return name;
               }

               set
               {
                  name = value;
               }
            }
        }
    }

    Program.cs

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

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Employee e1 = new Employee();
                e1.Name = "Kevin";
                Console.Write("Name is: {0:G}", e1.Name);
                Console.ReadLine();
            }
        }
    }

    Auto-Implemented Properties

    In C# 3.0 and later, auto-implemented properties make property-declaration more concise when no additional logic is required in the property accessors. They also enable client code to create objects. Below is the Employee class from the above example, modified to have auto-implemented properties.

    Employee.cs

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

    namespace ConsoleApplication1
    {
        class Employee
        {
            public string Name   // The Name auto-implemented property
            { get; set; }
        }
    }

    Static Properties

    A property may be declared as a static property by using the static keyword. This makes the property available to callers at any time, even if no instance of the class exists.

    Below is an example of static properties with the NumberOfEmployees being assigned a value before the object is instantiated.

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

    namespace properties2
    {
        public class Employee
        {
            public static int NumberOfEmployees;
            private static int counter;
            private string name;

            // A read-write instance property:
            public string Name
            {
                get { return name; }
                set { name = value; }
            }

            // A read-only static property:
            public static int Counter
            {
                get { return counter; }
            }

            // A Constructor:
            public Employee()
            {
                // Calculate the employee's number:
                counter = ++counter + NumberOfEmployees;
            }
        }

        class TestEmployee
        {
            static void Main()
            {
                Employee.NumberOfEmployees = 68;
                Employee e1 = new Employee();
                e1.Name = "Lotta Worken";

                System.Console.WriteLine("Employee number: {0}", Employee.Counter);
                System.Console.WriteLine("Employee name: {0}", e1.Name);
                System.Console.ReadLine();
            }
        }

    }

    Accessing Properties in the Base Class

    When a class is derived from a base class, the property of the base class can be hidden if the derived class has a property with the same name. Below is an example of how to access the property in the base class when this happens.

    public class Employee
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }

    public class Manager : Employee
    {
        private string name;

        // Notice the use of the new modifier:
        public new string Name
        {
            get { return name; }
            set { name = value + ", Manager"; }
        }
    }

    class TestHiding
    {
        static void Main()
        {
            Manager m1 = new Manager();

            // Derived class property.
            m1.Name = "Smithe";

            // Base class property.
            ((Employee)m1).Name = "Joe";

            System.Console.WriteLine("Name in the derived class is: {0}", m1.Name);
            System.Console.WriteLine("Name in the base class is: {0}", ((Employee)m1).Name);
            System.Console.ReadLine();

        }
    }

    Top



    Strings

    A string is an object of type String whose value is text. Internally, the text is stored as a sequential read-only collection of Char objects (UTF-16).

    • The string keyword is an alias for String. Therefore, String and string are equivalent, and you can use whichever naming convention you prefer.

    • Although string is a reference type, the equality operators (== and !=) are defined to compare the values of string objects, not references. This makes testing for string equality more intuitive.

    Testing for String Equality

    string x = "abc"; //Alias for String
    String y = "abc";

    if (x == y)
    {
        Console.WriteLine("Equal");
    }

    // Prints Equal

    • The String.Length property returns the number of Char objects (graphemes) in this instance. Note: This may not be the same as the number of Unicode characters as some character objects could be coded in only one byte. Unicode characters are coded in two bytes.

    • C# strings do NOT end will a null character as do the strings in C and C++. In C# nulls can be embedded within the strings. The foreach loop can be used to enumerate an array of strings.

    Foreach Enumerating Array printing String Value and Length

    string[] dogs = { "Collie", "Corgi", "Dalmation" };

    foreach (string dog in dogs)
    {
        Console.WriteLine("Dog's name is: {0} with length {1}", dog, dog.Length);
    }

    // Dog's name is: Collie with length 6
    // Dog's name is: Corgi with length 5
    // Dog's name is: Dalmation with length 9

    • Strings are immutable -- the contents of a string object can NOT be changed after the object is created, although the syntax makes it appear as if you can do this. For example, in the code below the compiler actually creates a new string object to hold the new sequence of characters. The original string, which contained only "H", is released for garbage collection. The System.Text.StringBuilder class can be used when you want to modify a string without creating a new object. For example, using the StringBuilder class can boost performance when concatenating many strings together in a loop.

    Immutable Strings

    string x = "H";
    String x += "ello World";

    // Two Strings are created

    String Formats
    .String Standard and Custom Formats



    String Standard and Custom Formats

    using System;

    namespace DataFormatExamples
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("-------------------------------------------");
                Console.WriteLine("--- Standard and Custom Numeric Formats ---");
                Console.WriteLine("-------------------------------------------");
                int k = 2000;
                Console.WriteLine("Default format: {0}\n", k);

                // Standard Numeric Formats
                Console.WriteLine("G is: {0:G}", k);
                Console.WriteLine("F is: {0:F}", k);
                Console.WriteLine("C is: {0:C}", k);
                Console.WriteLine("N is: {0:N}", k);
                Console.WriteLine("P is: {0:P}\n", k);

                // Custom Numeric Formats
                Console.WriteLine("0,0.000 is: {0:0,0.000}", k);
                Console.WriteLine("#-#-## is: {0:#-#-##}\n", k);

                //String.Format Method
                DateTime dat = new DateTime(2013, 9, 23, 7, 43, 0);
                string city = "Homer";
                double humidity = 0.75;
                string output = String.Format("Format Method: At {0} in {1}, the humidity was {2:P}.\n",
                                              dat, city, humidity);
                Console.WriteLine(output);
            }
        }
    }

    Top


    DateTime Structures



    DateTime structures represents an instant in time, typically expressed as a date and time of day.

    • Internally, all DateTime values are represented as the number of ticks (the number of 100-nanosecond intervals) that have elapsed since 12:00:00 midnight, January 1, 0001.

    • DateTime can be formatted with the Standard or Custom Date and Time Formats.


    • DateTime Examples
    .DateTime Formatting


    Top


    Interfaces



    An interface defines a contract defining the features that must be in any class that implements the interface. An interface name begins with the upper-case letter "I" by convention, eg ICar.cs. It has no state (no fields) and contains only the signatures for methods, properties, events and indexers.

    • An interface can NOT contain constants, fields, operators, instance constructors, destructors, or types. Interface members are automatically public, and they can NOT include any access modifiers in the interface definition. Members also can NOT be static.

    • Classes and Structs can implement multiple interfaces which allows them to obtain behavioral declarations from multiple sources. That capability is important in C# because the language does NOT support multiple inheritance of classes. In addition, you must use an interface if you want to simulate inheritance for structs, because structs do not inheritance.
    Top


    Command Line Compiler



    The command line compiler (CSC.exe) is located in framework directory, which is located at C:\Windows\Microsoft.NET\Framework\. Set the path to run the command line compiler by entering the command:

      set PATH=%PATH%;C:\Windows\Microsoft.NET\Framework\V4.0.30319.
    



    It is a good convention to have the file name be the same as the class name, with one class per file. However that convention is NOT required by the CSC compiler. In fact you could have several classes in one file.

    With the command line compiler you can build three types of applications:

    1. Console App - csc /t:exe (this is the default)
    2. Windows App - csc /t:winexe
    3. Library App - csc /t:library


    .NET Decompilers

    Decompilers allow you to see inside .NET assemblies (.dll, .exe). They are used by .NET developers to understand the inner workings of code libraries, to show the differences between two versions of the same assembly, and to show how the various parts of a CLI application interact with each other. They are also used to verify the correct versions of the components are in the assembly and to verify your obfuscation is effective.

    One of the first .NET assembly browsers was .NET Reflector written by Lutz Roeder in 2001. In 2008 Red Gate Software announced responsibility for .NET Reflector and it became a commercial product in 2011 with their version 7 release. Today Red Gate contains different configurations of .NET Reflector including a plugin for Visual Studio.

    Soon after the commercial version of .NET Reflector version 7 was released, several open-source .NET assembly browsers were created. One is called ILSpy and is available from GitHub. ILSpy is also included with the open-source SharpDevelop IDE for .NET development.

    ILSpy Decompiler and Object Browser
    .ILSpy Decompiler



    Note: Another option is to use the Intermediate Language Disassembler (ILDASM) is included with Visual Studio (ildasm.exe). ILDASM can be run from the developer command window (Visual Studio Tools subdirectory).


    Visual Studio - Console Application



    To create a Class library in a console application: right-click on the solution name in the Solution Explorer. Select <Add>, <New Project>, and then <Class Library>. The project in bold is the start-up project, you will never want a class library to be a start-up project. If you run the start-up project by using <Start without Debugging> Visual Studio will display the program results in a console window with a "Press any key to continue" message. (ie VS shows the console window as if you had added a Console.Read at the end of you program.)

    If you rename the class library .cs file using the Solution Explorer (eg Class1.cs => Greeting.cs), then VS will ask if it should rename all project references to the old associated class name to the new class name (Class1 to Greeting).

    You need to add a reference to the library project (just as is required with the command line compiler). In VS under the start-up project in the Solution Explorer, right click on References and select <Add Reference>. Then select the newly created library under the Projects tab and hit <OK>. Adding this reference ensures VS will compile the library file before the start-up project and ensures the library file will be included in the assembly. After you add the new library to the start-up project with a "using" statement, then intellisense will be able to find the new library. A short cut is to type the name of the class (eg Greeting) and then allow intellisense to add the using statement.

    Top


    Naming Conventions



    1. Namespaces - Pascal Case. The first letter of every word in the name is capitalized with no underscores. For example: MyNewNamespace. Pascal Case also means acronyms of three or more letters should only have the first letter capitalized (MyXmlNamespace instead of
      MyXMLNamespace).

    2. Assemblies - If an assembly contains only one namespace, they should use the same name as the filename. Otherwise, assemblies should follow the normal Pascal Case format.

    3. Classes and Structures - Pascal Case. No underscores or leading C, cls, or I. Classes should not have the same name as the namespace in which they reside. Any acronyms of three or more letters should be pascal case, not all caps. Try to avoid abbreviations, and try to always use nouns.

    4. Interfaces - Follow class naming conventions, but start the name with I and capitalize the letter following the I. Example: IFoo The I prefix helps to differentiate between Interfaces and classes and also to avoid name collisions.

    5. Functions - Pascal Case. No underscores except in the event handlers.

    6. Properties and Public Member Variables - Pascal Case. No underscores.

    7. Parameters and Procedure-level Variables - Camel Case. Camel Case is the same as Pascal case, but the first letter of the first word is lowercased.

    8. Class-level Private and Protected Variables - Camel Case with a leading underscore. Always indicate protected or private The leading character helps to prevent name collisions in constructors (a parameter and a private variable having the same name)..

    9. Constants - Pascal Case. The use of SCREAMING_CAPS is discouraged.

    10. Controls on Forms - Pascal Case with a prefix that identifies it as being part of the UI. eg. txtCustomerName, btnSave, ddlCompany, chkMailList, dgResults.
    Example Program Using All Naming Conventions
    using System;
    namespace MyExampleNamespace
    {
        public class Customer : IDisposable
        {
            private string _customerName;
            public string CustomerName
            {
                get
                {
                    return _customerName;
                }
                set
                {
                    _customerName = value;
                    _lastUpdated = DateTime.Now;
                }
            }
            private DateTime _lastUpdated;
            public DateTime LastUpdated
            {
                get
                {
                    return _lastUpdated;
                }
                private set
                {
                    _lastUpdated = value;
                }
            }
            public void UpdateCustomer(string newName)
            {
                if (!newName.Equals(CustomerName))
                {
                    CustomerName = newName;
                }
            }
            public void Dispose()
            {
                //Do nothing
            }
        }
    }
    Top


    Visual Studio Keyboard Shortcuts



    Auto Text Formatting => Select all text then <CTRL><E> then <CTRL<F>.
        
    Comment Block of Code=> Select all text then <CTRL><K> then <CTRL<C>.
    
    Uncomment Block of Code=> Select all text then <CTRL><K> then <CTRL<U>.
        
    Vertical Block Selection=> <ALT><left mouse button>.
    
    Intellisense Resolve Error => <CTRL><.>
    




    Note: See Visual Studio Keyboard Shortcuts for more VS shortcuts.

    References

    1. Introduction to C# - Anders Hejlsberg
    2. A C# Crash Course - RB Whitaker's Wiki
    3. Programming Concepts explains programming concepts that can be used in C#.
    4. C# Fundamentals - Microsoft Channel 9
    5. Quick Technology Finder for the .NET Framework - Microsoft Developer Network.
    6. Getting Started with Visual Studio - Visual Studio Tutorials.
    7. C# Beginning to Intermediate - C# Station
    8. Programming in C# Jump Start - Channel 9
    9. An online version of DZone C# Refcardz by Jon Skeet
    10. DateTime Structure - Microsoft Developer Network.
    11. TimeSpan Structure - Microsoft Developer Network.
    12. Calendar Class - Microsoft Developer Network.
    13. Strings (C# Programming Guide) - Microsoft Developer Network.
    14. Strings in C# and .NET - Microsoft Developer Network.
    15. DateTimeStyles Enumeration - Microsoft Developer Network.
    16. Custom Date and Time Format Strings - Microsoft Developer Network.
    17. Standard Date and Time Format Strings - Microsoft Developer Network.
    18. Standard TimeSpan Format Strings - Microsoft Developer Network.
    19. Custom TimeSpan Format Strings - Microsoft Developer Network.
    20. Properties (C# Programming Guide) - Microsoft Developer Network.
    21. Properties - Microsoft Developer Network.
    22. Properties Tutorial - Microsoft Developer Network.
    23. Using Properties (C# Programming Guide) - Microsoft Developer Network.
    24. Auto-Implemented Properties (C# Programming Guide) - Microsoft Developer Network.
    25. Accessors - Microsoft Developer Network.
    26. Passing Parameters (C# Programming Guide) - Microsoft Developer Network.
    Top