Thursday, December 13, 2012

Struct Vs Class in C#


·         Structs are value types and classes are reference types.
·         Value type instances are allocated on the stack. Reference type instances are allocated on the heap.
·         In .Net the struct and class declarations differentiate between reference types and value types.
·         When you pass around a reference type there is only one actually stored. All the code that accesses  the instance is accessing the same one.
·        When you pass around a value type each one is a copy. All the code is working on its own copy.
This can be shown with an example:
struct MyStruct
{
    string MyProperty { get; set; }
}
void ChangeMyStruct(MyStruct input)
{
   input.MyProperty = "new value";
}

// Create value type
MyStruct testStruct = new MyStruct { MyProperty = "initial value" };
ChangeMyStruct(testStruct);
// Value of testStruct.MyProperty is still "initial value"
//  the method changed a new copy of the structure.

For a class this would be different:

class MyClass
{
    string MyProperty { get; set; }
}
void ChangeMyClass(MyClass input)
{
   input.MyProperty = "new value";
}
// Create reference type
MyClass testClass = new MyClass { MyProperty = "initial value" };
ChangeMyClass(testClass);

// Value of testClass.MyProperty is now "new value"
// the method changed the instance passed.

·         Classes can be nothing - the reference can point to a null.
·         Structs are the actual value - they can be empty but never null. For this reason structs always have a default constructor with no parameters.
·         The struct can't use the protected or protected internal modifier. The class can use all the access modifiers.
·         A struct always has a built-in public default constructor. This means that a struct is always instantiable whereas a class might not be since all its constructors could be private.
class NonInstantiable
{
    private NonInstantiable() // ok
    {
    }
}

struct Direct
{
    private Direct() // compile-time error
    {
    }
}

·         A structs static constructor is not triggered by calling the structs default constructor. It is for a class.
struct Direct
{
//static constructor not called when new instance is created by //statement i.e.  new Direct()
static Direct()      
{
        Console.WriteLine("This is not written");
 }
}

    static void Main()
    {
       //static constructor not called when new instance is created
        Direct local = new Direct();
    }

class Direct
{
//static constructor called when new instance is created by statement i.e.  new Direct()
 static Direct()      
{
        Console.WriteLine("This is written");
                }
}

    static void Main()
    {
       //static constructor called when new instance is created
        Direct local = new Direct();
    }
·         A struct instance cannot be null. A class instance can be null.
·         A struct type cannot use the as operator. A class can use as operator.
  SampleStruct obj2 = obj1 as SampleStruct; //compile time error
  SampleClass obj2 = obj1 as SampleClass; //Compiles OK
·         A struct cannot have a destructor but a class can have a destructor. A destructor is just an override of object.Finalize in disguise, and structs, being value types, are not subject to garabge collection.
~SampleStruct() //compile time error
  ~SampleClass() //Compiles OK
·         You can initialize fields in a class at their point of declaration. For example:
class Indirect
{
    //...
    private int field = 42;  
}
You can't do this for fields in a struct. For example:
struct Direct
{
    //...
    private int field = 42; // compile-time error
}

·         Classes inherit Object.Equals which implements identity equality whereas structs inherit ValueType.Equals which implements value equality.
·         A struct is implicitly sealed, a class isn't.
·         A struct can't be abstract, a class can.
·         A struct can't extend another class, a class can.
·         A struct can't declare protected members (e.g. fields, nested types) a class can.
·         A struct can't declare abstract function members, an abstract class can.
·         A struct can't declare virtual function members, a class can.
·         A struct can't declare sealed function members, a class can.
·         A struct can't declare override function members, a class can. The one exception to this rule is that a struct can override the virtual methods of System.ObjectEquals(), and GetHashCode(), and ToString().



1 comment: