Personal notes on software development.
For Java technologies check my dedicated site

Pages

C# Types

In .NET (and therefore C#) there are two main sorts of type: reference types and value types.

A reference type is a type which has as its value a reference to the appropriate data rather than the data itself. While reference types have a layer of indirection between the variable and the real data, value types don't. Variables of a value type directly contain the data. Assignment of a value type involves the actual data being copied. For more information about the two types and parameter passing (by reference or by value) in C# check this two articles:


So the C# typing system contains the following categories:
  • 1. Value types: Variables that are "Value Types" store data (in contrast with those that are "Reference Types" which store references to the data, instead of the data itself). These can be subdivide in:
    1.1. Enumerations (enum);
    1.2. Structs, these can be:
    1.2.1. User defined structs;
    1.2.2. bool;
    1.2.3. Numeric types such as:
    1.2.3.1. Integral types (sbyte, byte, char, short, ushort, int, uint, long, ulong);
    1.2.3.2. Floating-point types (float, double);
    1.2.3.3. decimal;
  • 2. Reference types: (referred to as objects) store references to the data instead of the data itself (similar to a pointer).
    2.1. Built-in reference types: dynamicobjectstring;
    2.2. User defined (trough keywords used to declare reference types: class, interface, delegate); 
  • 3. Pointer types
Notes:
String - while numerical and boolean types are implemented as structs (value types), the string type is implemented has a reference type. But the string type has some peculiar implementation properties that makes it act differently from an ordinary object and similar to a value type, for example:
  • The equality operators (== and !=) are defined to compare the values of string objects, not references.
  • Strings are immutable: the contents of a string object cannot be changed after the object is created, although the syntax makes it appear as if you can do this;
  • "string" is an alias for String class in the .NET Framework;
  • see the documentation for more details: string and String class;
Char - is considered an Integral Type (along with int, byte, etc.).


Built-in Value Types:

C# offers the usual intrinsic (built-in/primitive) types you expect in a modern language, each of which maps to an underlying type supported by the .NET CTS (this mapping of C# primitive types to underlying .NET types ensures that objects created in C# can be used interchangeably with objects created in any other language compliant with the .NET CTS, such as Visual Basic).


C# Type .NET Framework Type Type Suffix
Description
ByteSystem.Byte
8 bit unsigned (0 to 255)
SbyteSystem.SByte
8 bit Signed values (–128 to 127)
ShortSystem.Int16
16 bit Signed short values (–32,768 to 32,767)
UshortSystem.UInt16
16 bit Unsigned short values (0 to 65,535)
IntSystem.Int32
32 bit signed integer (–2,147,483,648 to 2,147,483,647)
UintSystem.UInt32U or u32 bit unsigned integer (0 to 4,294,967,295)
LongSystem.Int64L or l64 bit signed integer
UlongSystem.UInt64UL or ul64 bit unsigned integer
FloatSystem.SingleF or f32 bit; IEEE comform Floating-Point-Value
DoubleSystem.DoubleD or d64 bit; IEEE comform Floating-Point-Value
DecimalSystem.DecimalM or m128 bit Floating-Point-Value Decimal Fixed-precision value up to 28 digits and the
position of the decimal point; this is typically used in financial calculations;
requires the suffix “m” or “M”
BoolSystem.Boolean
1 bit;  (true or false)
CharSystem.Char
16 bit (Unicode character)

Notes:
  • Suffixes: The compiler assumes that any number with a decimal point is a double unless you tell it otherwise. You must therefore use the f suffix for a float, and the m for a decimal.

User-defined Value Types:

Built-in Reference Types:

User-defined Reference Types:

References



Constants

Constant names are typically written in Pascal notation or all caps (e.g. BoilingPoint or BOILINGPOINT).Constants come in three flavors:
  • literals, example:
    x = 32;
    (The value 32 is a literal constant);
  • symbolic constants (assign a name to a constant value), example:
    const int FreezingPoint = 32;
    (32 is a literal constant, and FreezingPoint is a symbolic constant of type int);
  • enumerations:
    Enumerations can provide a powerful alternative to constants. An enumeration is a distinct value type, consisting of a set of named constants (called the enumerator list).
    Enumerations let you establish a relation between constants, i.e. instead of doing this:
    const int LightJacketWeather = 60;
    const int SwimmingWeather = 72;
    const int WickedCold = 0;
    You can do this:
    enum Temperatures
    {
       WickedCold = 0,
       FreezingPoint = 32,
       LightJacketWeather = 60,
       SwimmingWeather = 72,
       BoilingPoint = 212,
    }
    Access the constant values with:
    (int)Temperatures.BoilingPoint

    Learn more about enumerations.

Classes

Concepts:
  • "base class": ex. "Mammal" is a generalization of "Dog" and "Cat";
  • "subclass": ex. "Dog" and "Cat" are specialized classes of" Mammal" (Dog and Cat extends Mammal);
  • If you don't specify a constructor for a class, a default constructor is created automatically with no parameters. But after you specify one constructor (with any number of parameters) the default constructor will no longer be created;
  • When a subclass is instantiated the constructor of the base class is automatically called to first create an instance of the base class (if a constructor isn't specified the default base class constructor is called by default). Example:
    class MySubClass : MyBaseClass
    {
        public MySubClass() : base(4)
        {
            (...)           
        }
    }
    In this example we specify a constructor to call for the base class creation, one that takes an integer parameter (instead of the default parameter-less constructor).

  • virtual/override methods: if the base class has virtual methods each derived class is free to implement its own version of the method by specifying an override method. Example:
    On the base class:
    public virtual void DrawWindow( )
    On the Subclass:
    public override void DrawWindow( )
    {
        (...)
    }
    Note: only virtual, abstract or already marked has override methods can be overridden;
    More details here: Polymorphic Methods (using virtual and override)
  • Class modifiers: Controlling visibility of a class and its members
    • public: allows a member to be accessed by the member methods of other classes;
    • private: indicates that the member is visible only to member methods of its own class;
    • protected: extends visibility to methods of derived classes;
    • internal: extends visibility to methods of any class in the same assembly;
    • internal protected keyword pair: allows access to members of the same assembly (internal) or derived classes (protected). You can think of this designation as internal or protected.
  • Abstract Classes
    • if a class has (at least) one abstract method, the class must be declared itself an abstract class;
    • an abstract method has no implementation. It creates a method name and signature that must be implemented in all derived classes;
    • an abstract class can't be instantiated (an abstract class is intended to be derived from and to provide a template for its subclasses to follow);
    • Example:
      abstract public class MyClass{ 
       abstract public void myAbstractMethod();
      }
      Note: Because an abstract method can have no implementation, there are no braces, only a semicolon.
    • abstract class vs interface: by specifying abstract methods and abstract class can work like an interface. But, an abstract class can provide implementation of other non abstract methods that can be inherited by sub-classes (Interfaces on the other hand cannot provide any implementation).
      It's also good to remember that a class can only have one base class but it can implement any number of interfaces;
  • Sealed Classes
    • a sealed class doesn’t allow classes to derive from it;
    • a sealed class in C# is the equivalent of a final class in Java
    • classes are most often marked sealed to prevent accidental inheritance;
    • Example:
      sealed public class MyClass{ 
       (...)
      }
  • The Object class: All C# Class derive from System.Object. Interestingly, this includes value types (primitive datatypes such as int can be treated as though they inherit from Object).
    This base class provides a set of virtual methods that sublcasses can override:
    Method Description
    Equals() Evaluates whether two objects are equivalent
    GetHashCode() Allows objects to provide their own hash function for use in collections
    GetType() Provides access to the type object
    ToString() Provides a string representation of the object
    Finalize() Cleans up unmanaged resources; implemented by a destructor
    MemberwiseClone() Creates copies of the object; should never be implemented by your type
    ReferenceEquals() Evaluates whether two objects refer to the same instance


















  • Nested Classes
      A nested class is a class that is defined inside another class. The contained, inner class is called a nested class, and the class that contains it is called, simply, the outer class.
    • Nested classes are used when the contained class acts as a helper class (the contained class might exist only to serve the outer class, and there might be no reason for it to be otherwise visible).
    • Nested classes have the advantage of access to all the members of the outer class. A
      method of a nested class can access private members of the outer class.
    • Example:
      class MyOuterClass
      {
          private int x = 5;
      
          public MyOuterClass()
          {           
              MyNestedClass nested = new MyNestedClass();
              nested.incrementX(this);
      
              Console.WriteLine(x);
          }
      
          class MyNestedClass
          {
              public void incrementX(MyOuterClass outer){
                  outer.x++;
              }
          }
      }
      /*OUTPUT:
      6
      */
      Note: "MyNestedClass" is defined inside "MyOuterClass". Although the variable x is private, the nested class has entire access to it;










  • Case clauses

    Switch example

    class Program
    {
        enum MyEnum {A,B,C,D,F};
        private void printSelection(MyEnum myChoice)
        {
            switch (myChoice)
            {
                case MyEnum.A:
                    Console.Write("A");
                    break;
                case MyEnum.B: // fall through              
                case MyEnum.C:
                    Console.Write("B C");
                    break;
                case MyEnum.D:
                    Console.Write("D ");
                    goto case MyEnum.A; //goto statement
                default: //default value
                    Console.Write("You did not pick a valid choice");
                    break;
            }
            Console.Write("\n");
        }
        static void Main(string[] args)
        {
            Program p = new Program();
            MyEnum myChoice = MyEnum.A;
            p.printSelection(myChoice); //OUT: A
            myChoice = MyEnum.B;
            p.printSelection(myChoice); //OUT: B C
            myChoice = MyEnum.C;
            p.printSelection(myChoice); //OUT: B C
            myChoice = MyEnum.D;
            p.printSelection(myChoice); //OUT: D A
            myChoice = MyEnum.F;
            p.printSelection(myChoice); //OUT: You did not pick a valid choice
            Console.ReadKey();
        } 
    }
    Note: although we are using an enumeration in this switch example, you can also use strings or value types directly;


    Converting values:

    Example1:
    int num1; 
    string teste = "abc";
    int.TryParse(teste, out num1); //num1 will be assigned 0
    num1 = int.Parse(teste); //System.FormatException
    num1 = Convert.ToInt32(teste) ; // System.FormatException

    Example2:
    int num1; 
    string teste = null;
    int.TryParse(teste, out num1); //num1 will be assigned 0
    num1 = int.Parse(teste); //System.ArgumentNullException
    num1 = Convert.ToInt32(teste) ; //num1 will be assigned 0

    Example3, converting currency values:
    string str = "1,25€";
    decimal? price = decimal.Parse(str1, System.Globalization.NumberStyles.Currency);
    the code above will also work for the following strings:
    • "";
    • "         "; (Because Trim() is applied);
    • "0";
    • "1";
    • ",1";
    Note: the decimal separator depends on the local definitions, in some cases a "," is used in other the ".". If the current system is using a "," as the separator then using a "." will result in an exception.
    A simple solution could be achieved by replacing the "." for a ",":
    decimal? price = decimal.Parse(str.Replace('.',',').Trim(), 
                             System.Globalization.NumberStyles.Currency);

    NULL Values:

    When working with database data special care must be taken when DB null values are allowed. In particular, method  input parameters must be of type Object since the incoming value might be a DBNull instance instead of the expected data type. Additionally, a check must be made to determine whether or not the incoming value is a database NULL value.

    Example:
    protected string DisplayPrice(object unitPrice)
    {
       if (!Convert.IsDBNull(unitPrice))
          return ((decimal) unitPrice).ToString("C");
       else return "No price available";
    }

    Strings

    • string.IsNullOrEmpty(str);
    • string str = string.Empty;
    • str1.CompareTo(str2);

    Collections

    Resources:
    The .NET Framework provides specialized classes for data storage and retrieval. These classes provide support for stacks, queues, lists, and hash tables.

    NOTE: since .NET 2.0 and later you should use the generic collection classes in the System.Collections.Generic namespace, which provide greater type-safety and efficiency than their non-generic counterparts.

    • List is the generic class corresponding to ArrayList;
    • Dictionary is the generic class corresponding to Hashtable;
    • Collection is the generic class corresponding to CollectionBase. Collection can be used as a base class, but unlike CollectionBase it is not abstract, making it much easier to use;
    • ReadOnlyCollection is the generic class corresponding to ReadOnlyCollectionBase. ReadOnlyCollection is not abstract, and has a constructor that makes it easy to expose an existing List as a read-only collection;
    • The Queue, Stack, and SortedList generic classes correspond to the respective nongeneric classes with the same names;
    There are several generic collection types that do not have nongeneric counterparts:
    • LinkedList is a general-purpose linked list that provides O(1) insertion and removal operations.
    • SortedDictionary is a sorted dictionary with O(log n) insertion and retrieval operations, making it a useful alternative to SortedList.
    • KeyedCollection is a hybrid between a list and a dictionary, which provides a way to store objects that contain their own keys.
    Choose the System.Collections more appropriate to your problem:
    - Do you need a sequential list where the element is typically discarded after its value is retrieved?

    • Queue class (or the Queue generic class) gives FIFO behavior;
    • Stack class (or the Stack generic class)gives (LIFO) behavior.

    - Do you need to access the elements in a certain order, such as FIFO, LIFO, or random?
    • Queue (and generic version) class offers FIFO access
    • Stack (and generic version) class offer LIFO access.
    • LinkedList generic class allows sequential access either from the head to the tail or from the tail to the head.
    • The rest of the collections offer random access.

    - to be continued...

    Exceptions

    There are multiple Exceptions defined in .NET, each is implemented on its own class;
    All Exception classes derive from the class Exception;
    The base Class Exception has 2 main branches:

    • class SystemException: exceptions thrown from the .NET platform;
    • class ApplicationException: user defined Exceptions;
    Try Catch example:
     try
     {
         int num = int.Parse(str);
         Console.WriteLine("int:" + num);
     }
     catch (ArgumentNullException) //no need to define an exception variable
     {
         Console.WriteLine("Cant convert NULL to int.");
     }
     catch (Exception ex) //catches all other Exceptions
     {
         Console.WriteLine("OverFlow or Format Exception. "
             +"Details: " + ex.Message);
     }
     finally //always executed
     {
         Console.WriteLine("Teminated");
     }
    

    User defined exception example:
    class NaoNumericoException : ApplicationException
    {
        public NaoNumericoException(String valor, Exception innerException)
            : base("O valor " + valor + " não é um numero", innerException)
        {        
        }
    }

    Throwing an exception example:
    try
    {
        double num = double.Parse(str);
    }
    catch (Exception e)
    {
        throw new NaoNumericoException(str, e);
    }

    Base class "Exception" usefull properties/methods:
    • Message – Propriedade de leitura do tipo string que contém uma descrição da razão que levou ao lançamento da excepção.
    • InnerException – É uma referência para uma possível excepção anterior que tenha levado ao lançamento da excepção actual. Pode ser nula, indicando que esta excepção não foi lançada num bloco catch de outra excepção.
    • StackTrace – Propriedade de leitura do tipo string que indica a sequência de chamadas (stack trace) na altura em que a excepção foi lançada.

    No comments:

    Post a Comment