Monday, January 2, 2012

OOPs(Object-Oriented Programming) in C# programming



C# Programming:

 OOPs(Object-Oriented Programming)
·         Classes and Objects
·         Class Members
o    Properties and Fields
o    Methods
o    Constructors
o    Destructors
o    Events
o    Nested Classes
·         Access Modifiers and Access Levels
·         Instantiating Classes
·         Static (Shared) Classes and Members
·         Anonymous Types
·         Inheritance
o    Overriding Members
·         Interfaces
·         Abstract
·         Generics
·         Extension Methods
·         Delegates



Object-Oriented Programming is a technique to think a real word in term of objects.


Classes and Objects
--------------------------------------------------------------------------------

The terms class and object are sometimes used interchangeably, but in fact, classes describe the type of objects, while objects are usable instances of classes. So, the act of creating an object is called instantiation. Using the blueprint analogy, a class is a blueprint, and an object is a building made from that blueprint.

To define a class:

class SampleClass
{    }

Both Visual Basic and C# also provide a light version of classes called structures that are useful when you need to create large array of objects and do not want to consume too much memory for that.

To define a structure:

struct SampleStruct
{
}

Class Members
Each class can have different class members that include properties that describe class data, methods that define class behavior, and events that provide communication between different classes and objects.
Properties and Fields
Fields and properties represent information that an object contains. Fields are like variables because they can be read or set directly.
To define a field:
class SampleClass{  
       public string sampleField;
}

Properties have get and set procedures, which provide more control on how values are set or returned.
Both C# and Visual Basic allow you either to create a private field for storing the property value or use so-called auto-implemented properties that create this field automatically behind the scenes and provide the basic logic for the property procedures.
To define an auto-implemented property:
class SampleClass{
    public int SampleProperty { get; set; }
}
If you need to perform some additional operations for reading and writing the property value, define a field for storing the property value and provide the basic logic for storing and retrieving it:
class SampleClass{
    private int _sample;
    public int Sample
    {  // Return the value stored in a field.
        get { return _sample; }
        // Store the value in the field.
        set { _sample = value; }
    }
}
Most properties have methods or procedures to both set and get the property value. However, you can create read-only or write-only properties to restrict them from being modified or read. In Visual Basic you can use ReadOnly and WriteOnly keywords. In C#, you can omit the get or set property method. However, in both Visual Basic and C#, auto-implemented properties cannot be read-only or write-only.
For more information, see
Ø  get
Ø  set



Methods
A method is an action that an object can perform.


To define a method of a class:
class SampleClass
{
    public int sampleMethod(string sampleParam)
    {        // Insert code here
    }
}
A class can have several implementations, or overloads, of the same method that differ in the number of parameters or parameter types.
To overload a method:
public int sampleMethod(string sampleParam) {};
public int sampleMethod(int sampleParam) {}
In most cases you declare a method within a class definition. However, both Visual Basic and C# also support extension methods that allow you to add methods to an existing class outside the actual definition of the class.
For more information, see:
Ø  Methods
Ø  Extension Methods


Extension Methods

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.
The most common extension methods are the LINQ standard query operators that add query functionality to the existing System.Collections.IEnumerable and System.Collections.Generic.IEnumerable(Of T) types. To use the standard query operators, first bring them into scope with a using System.Linq directive. Then any type that implements IEnumerable(Of T) appears to have instance methods such as GroupBy, OrderBy, Average, and so on. You can see these additional methods in IntelliSense statement completion when you type "dot" after an instance of an IEnumerable(Of T) type such as List(Of T) or Array.
The following example shows how to call the standard query operator OrderBy method on an array of integers. The expression in parentheses is a lambda expression. Many standard query operators take lambda expressions as parameters, but this is not a requirement for extension methods. For more information, see Lambda Expressions (C# Programming Guide).

class ExtensionMethods2   
{
    static void Main()
    {           
        int[] ints = { 10, 45, 15, 39, 21, 26 };
        var result = ints.OrderBy(g => g);
        foreach (var i in result)
        {
            System.Console.Write(i + " ");
        }          
    }       
}
//Output: 10 15 21 26 39 45


Extension methods are defined as static methods but are called by using instance method syntax. Their first parameter specifies which type the method operates on, and the parameter is preceded by the this modifier. Extension methods are only in scope when you explicitly import the namespace into your source code with a using directive.
The following example shows an extension method defined for the System.String class. Note that it is defined inside a non-nested, non-generic static class:
namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' },
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }  
}
The WordCount extension method can be brought into scope with this using directive:
using ExtensionMethods;
And it can be called from an application by using this syntax:
string s = "Hello Extension Methods";
int i = s.WordCount();
In your code you invoke the extension method with instance method syntax. However, the intermediate language (IL) generated by the compiler translates your code into a call on the static method. Therefore, the principle of encapsulation is not really being violated. In fact, extension methods cannot access private variables in the type they are extending.
For more information, see How to: Implement and Call a Custom Extension Method (C# Programming Guide).
In general, you will probably be calling extension methods far more often than implementing your own. Because extension methods are called by using instance method syntax, no special knowledge is required to use them from client code. To enable extension methods for a particular type, just add a using directive for the namespace in which the methods are defined. For example, to use the standard query operators, add this using directive to your code:
using System.Linq;
(You may also have to add a reference to System.Core.dll.) You will notice that the standard query operators now appear in IntelliSense as additional methods available for most IEnumerable(Of T) types.
 Note
Although standard query operators do not appear in IntelliSense for String, they are still available.
 Binding Extension Methods at Compile Time
________________________________________
You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself. In other words, if a type has a method named Process(int i), and you have an extension method with the same signature, the compiler will always bind to the instance method. When the compiler encounters a method invocation, it first looks for a match in the type's instance methods. If no match is found, it will search for any extension methods that are defined for the type, and bind to the first extension method that it finds. The following example demonstrates how the compiler determines which extension method or instance method to bind to.
 Example
________________________________________
The following example demonstrates the rules that the C# compiler follows in determining whether to bind a method call to an instance method on the type, or to an extension method. The static class Extensions contains extension methods defined for any type that implements IMyInterface. Classes A, B, and C all implement the interface.
The MethodB extension method is never called because its name and signature exactly match methods already implemented by the classes.
When the compiler cannot find an instance method with a matching signature, it will bind to a matching extension method if one exists.



// Define an interface named IMyInterface.
namespace DefineIMyInterface
{
    using System;

    public interface IMyInterface
    {
        // Any class that implements IMyInterface must define a method
        // that matches the following signature.
        void MethodB();
    }
}
// Define extension methods for IMyInterface.
namespace Extensions
{
    using System;
    using DefineIMyInterface;

    // The following extension methods can be accessed by instances of any
    // class that implements IMyInterface.
    public static class Extension
    {
        public static void MethodA(this IMyInterface myInterface, int i)
        {
            Console.WriteLine
                ("Extension.MethodA(this IMyInterface myInterface, int i)");
        }

        public static void MethodA(this IMyInterface myInterface, string s)
        {
            Console.WriteLine
                ("Extension.MethodA(this IMyInterface myInterface, string s)");
        }
        // This method is never called in ExtensionMethodsDemo1, because each
        // of the three classes A, B, and C implements a method named MethodB
        // that has a matching signature.
        public static void MethodB(this IMyInterface myInterface)
        {
            Console.WriteLine
                ("Extension.MethodB(this IMyInterface myInterface)");
        }
    }
}
// Define three classes that implement IMyInterface, and then use them to test
// the extension methods.
namespace ExtensionMethodsDemo1
{
    using System;
    using Extensions;
    using DefineIMyInterface;

    class A : IMyInterface
    {
        public void MethodB() { Console.WriteLine("A.MethodB()"); }
    }

    class B : IMyInterface
    {
        public void MethodB() { Console.WriteLine("B.MethodB()"); }
        public void MethodA(int i) { Console.WriteLine("B.MethodA(int i)"); }
    }

    class C : IMyInterface
    {
        public void MethodB() { Console.WriteLine("C.MethodB()"); }
        public void MethodA(object obj)
        {
            Console.WriteLine("C.MethodA(object obj)");
        }
    }

    class ExtMethodDemo
    {
        static void Main(string[] args)
        {
            // Declare an instance of class A, class B, and class C.
            A a = new A();
            B b = new B();
            C c = new C();

            // For a, b, and c, call the following methods:
            //      -- MethodA with an int argument
            //      -- MethodA with a string argument
            //      -- MethodB with no argument.

            // A contains no MethodA, so each call to MethodA resolves to
            // the extension method that has a matching signature.
            a.MethodA(1);           // Extension.MethodA(object, int)
            a.MethodA("hello");     // Extension.MethodA(object, string)

            // A has a method that matches the signature of the following call
            // to MethodB.
            a.MethodB();            // A.MethodB()

            // B has methods that match the signatures of the following
            // nethod calls.
            b.MethodA(1);           // B.MethodA(int)
            b.MethodB();            // B.MethodB()

            // B has no matching method for the following call, but
            // class Extension does.
            b.MethodA("hello");     // Extension.MethodA(object, string)

            // C contains an instance method that matches each of the following
            // method calls.
            c.MethodA(1);           // C.MethodA(object)
            c.MethodA("hello");     // C.MethodA(object)
            c.MethodB();            // C.MethodB()
        }
    }
}
/* Output:
    Extension.MethodA(this IMyInterface myInterface, int i)
    Extension.MethodA(this IMyInterface myInterface, string s)
    A.MethodB()
    B.MethodA(int i)
    B.MethodB()
    Extension.MethodA(this IMyInterface myInterface, string s)
    C.MethodA(object obj)
    C.MethodA(object obj)
    C.MethodB()
 */

 General Guidelines
________________________________________
In general, we recommend that you implement extension methods sparingly and only when you have to. Whenever possible, client code that must extend an existing type should do so by creating a new type derived from the existing type. For more information, see Inheritance (C# Programming Guide).
When using an extension method to extend a type whose source code you cannot change, you run the risk that a change in the implementation of the type will cause your extension method to break.
If you do implement extension methods for a given type, remember the following two points:

•    An extension method will never be called if it has the same signature as a method defined in the type.
•    Extension methods are brought into scope at the namespace level. For example, if you have multiple static classes that contain extension methods in a single namespace named Extensions, they will all be brought into scope by the using Extensions; directive.


Anonymous Types
Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first. The type name is generated by the compiler and is not available at the source code level. The type of each property is inferred by the compiler.
You create anonymous types by using the new operator together with an object initializer. For more information about object initializers, see Object and Collection Initializers (C# Programming Guide).
The following example shows an anonymous type that is initialized with two properties named Amount and Message.
var v = new { Amount = 108, Message = "Hello" };
// Rest the mouse pointer over v.Amount and v.Message in the following
// statement to verify that their inferred types are int and string.
Console.WriteLine(v.Amount + v.Message);
Anonymous types typically are used in the select clause of a query expression to return a subset of the properties from each object in the source sequence. For more information about queries, see LINQ Query Expressions (C# Programming Guide).
Anonymous types contain one or more public read-only properties. No other kinds of class members, such as methods or events, are valid. The expression that is used to initialize a property cannot be null, an anonymous function, or a pointer type.
The most common scenario is to initialize an anonymous type with properties from another type. In the following example, assume that a class exists that is named Product. Class Product includes Color and Price properties, together with other properties that you are not interested in. Variable products is a collection of Product objects. The anonymous type declaration starts with the new keyword. The declaration initializes a new type that uses only two properties from Product. This causes a smaller amount of data to be returned in the query.
If you do not specify member names in the anonymous type, the compiler gives the anonymous type members the same name as the property being used to initialize them. You must provide a name for a property that is being initialized with an expression, as shown in the previous example. In the following example, the names of the properties of the anonymous type are Color and Price.
var productQuery =
    from prod in products
    select new { prod.Color, prod.Price };
foreach (var v in productQuery)
{    Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);}
Typically, when you use an anonymous type to initialize a variable, you declare the variable as an implicitly typed local variable by using var. The type name cannot be specified in the variable declaration because only the compiler has access to the underlying name of the anonymous type. For more information about var, see Implicitly Typed Local Variables (C# Programming Guide).
You can create an array of anonymously typed elements by combining an implicitly typed local variable and an implicitly typed array, as shown in the following example.
var anonArray = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 }};

 Remarks
________________________________________
Anonymous types are class types that derive directly from object, and that cannot be cast to any type except object. The compiler provides a name for each anonymous type, although your application cannot access it. From the perspective of the common language runtime, an anonymous type is no different from any other reference type.
If two or more anonymous types in the same assembly have the same number and type of properties, in the same order, the compiler treats them as the same type. They share the same compiler-generated type information.
You cannot declare a field, a property, an event, or the return type of a method as having an anonymous type. Similarly, you cannot declare a formal parameter of a method, property, constructor, or indexer as having an anonymous type. To pass an anonymous type, or a collection that contains anonymous types, as an argument to a method, you can declare the parameter as type object. However, doing this defeats the purpose of strong typing. If you must store query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type.
Because the Equals and GetHashCode methods on anonymous types are defined in terms of the Equals and GetHashcode methods of the properties, two instances of the same anonymous type are equal only if all their properties are equal.


Constructors
Constructors are class methods that are executed automatically when an object of a given type is created. Constructors usually initialize the data members of the new object. A constructor can run only once when a class is created. Furthermore, the code in the constructor always runs before any other code in a class. However, you can create multiple constructor overloads in the same way as for any other method.
Constructors are class methods that are executed when an object of a class or struct is created. They have the same name as the class or struct, and usually initialize the data members of the new object.
A class or struct may have multiple constructors that take different arguments. Constructors enable the programmer to set default values, limit instantiation, and write code that is flexible and easy to read.
If you do not provide a constructor for your object, C# will create one by default that instantiates the object and sets member variables to the default values as listed in Default Values Table (C# Reference). Static classes and structs can also have constructors.
To define a constructor for a class:
public class SampleClass
{
    public SampleClass()
    {  // Add code here   }
}
For more information, see:

Destructors
Destructors are used to destruct instances of classes. In the .NET Framework, the garbage collector automatically manages the allocation and release of memory for the managed objects in your application. However, you may still need destructors to clean up any unmanaged resources that your application creates. There can be only one destructor for a class.
For more information about destructors and garbage collection in the .NET Framework, see Garbage Collection.

Events
Events enable a class or object to notify other classes or objects when something of interest occurs. The class that sends (or raises) the event is called the publisher and the classes that receive (or handle) the event are called subscribers. For more information about events, how they are raised and handled, see Handling and Raising Events.
•    C#
•    To declare an event in a class, use the event (C# Reference) keyword.
•    To raise an event, invoke the event delegate.
•    To subscribe to an event, use the += operator; to unsubscribe from an event, use the -= operator.
Nested Classes
A class defined within another class is called nested. By default, the nested class is private.
class Container
{
    class Nested
    {
        // Add code here.
    }
}
To create an instance of the nested class, use the name of the container class followed by the dot and then followed by the name of the nested class:
Container.Nested nestedInstance = new Container.Nested()
Access Modifiers and Access Levels
All classes and class members can specify what access level they provide to other classes by using access modifiers.
The following access modifiers are available:

       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 only be accessed by code in the same class.
      Protected
The type or member can only be accessed by code in the same class or in a derived 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 same assembly, or by any derived class in another assembly.
For more information, see Access Levels in Visual Basic and Access Modifiers (C# Programming Guide).

Instantiating Classes
To create an object, you need to instantiate a class, or create a class instance.
SampleClass sampleObject = new SampleClass();
After instantiating a class, you can assign values to the instance's properties and fields and invoke class methods.
// Set a property value.
sampleObject.sampleProperty = "Sample String";
// Call a method.
sampleObject.sampleMethod();
To assign values to properties during the class instantiation process, use object initializers:
// Set a property value.
SampleClass sampleObject = new SampleClass
    { FirstProperty = "A", SecondProperty = "B" };

For more information, see:

•    new Operator
•    Object and Collection Initializers


Static (Shared) Classes and Members
A static (shared in Visual Basic) member of the class is a property, procedure, or field that is shared by all instances of a class.
To define a static (shared) member:
static class SampleClass
{
    public static string SampleString = "Sample String";
}
To access the static (shared) member, use the name of the class without creating an object of this class:
Console.WriteLine(SampleClass.SampleString);
Static (shared) classes in C# and modules in Visual Basic have static (shared) members only and cannot be instantiated. Static (shared) members also cannot access non-static (non-shared) properties, fields or methods
For more information, see:

•    C#
•    static (C# Reference)

Anonymous Types
Anonymous types enable you to create objects without writing a class definition for the data type. Instead, the compiler generates a class for you. The class has no usable name and contains the properties you specify in declaring the object.
To create an instance of an anonymous type:
// sampleObject is an instance of a simple anonymous type.
var sampleObject =
    new { FirstProperty = "A", SecondProperty = "B" };
For more information, see:

•    C#: Anonymous Types

 Inheritance
________________________________________
Inheritance enables you to create a new class that reuses, extends, and modifies the behavior that is defined in another class. The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. However, all classes in both C# and Visual Basic implicitly inherit from the Object class that supports .NET class hierarchy and provides low-level services to all classes.
 Note
Managed languages in the .NET Framework do not support multiple inheritance, i.e. you can specify only one base class for a derived class.
To inherit from a base class:
class DerivedClass:BaseClass{}
By default all classes can be inherited. However, you can specify whether a class must not be used as a base class, or create a class that can be used as a base class only.
To specify that a class cannot be used as a base class:
public sealed class A { }
To specify that a class can be used as a base class only and cannot be instantiated:
public abstract class B { }

For more information, see:

•    sealed
•    abstract

Sealed
When applied to a class, the sealed modifier prevents other classes from inheriting from it. In the following example, class B inherits from class A, but no class can inherit from class B.
    class A {}   
    sealed class B : A {}
You can also use the sealed modifier on a method or property that overrides a virtual method or property in a base class. This enables you to allow classes to derive from your class and prevent them from overriding specific virtual methods or properties.
 Example
________________________________________
In the following example, Z inherits from Y but Z cannot override the virtual function F that is declared in X and sealed in Y.
    class X
    {
        protected virtual void F() { Console.WriteLine("X.F"); }
        protected virtual void F2() { Console.WriteLine("X.F2"); }
    }
    class Y : X
    {  sealed protected override void F() { Console.WriteLine("Y.F"); }
        protected override void F2() { Console.WriteLine("X.F3"); }
    }
    class Z : Y
    {
        // Attempting to override F causes compiler error CS0239.
        // protected override void F() { Console.WriteLine("C.F"); }

        // Overriding F2 is allowed.
        protected override void F2() { Console.WriteLine("Z.F2"); }
    }
When you define new methods or properties in a class, you can prevent deriving classes from overriding them by not declaring them as virtual.
It is an error to use the abstract modifier with a sealed class, because an abstract class must be inherited by a class that provides an implementation of the abstract methods or properties.
When applied to a method or property, the sealed modifier must always be used with override.
Because structs are implicitly sealed, they cannot be inherited.
For more information, see Inheritance (C# Programming Guide).
For more examples, see Abstract and Sealed Classes and Class Members (C# Programming Guide).
    sealed class SealedClass
    {
        public int x;
        public int y;
    }
    class SealedTest2
    {
        static void Main()
        {
            SealedClass sc = new SealedClass();
            sc.x = 110;
            sc.y = 150;
            Console.WriteLine("x = {0}, y = {1}", sc.x, sc.y);
        }
    }    // Output: x = 110, y = 150
In the previous example, you might try to inherit from the sealed class by using the following statement:
class MyDerivedC: SealedClass {} // Error
The result is an error message:
'MyDerivedC' cannot inherit from sealed class 'SealedClass'.
abstract (C# Reference)
The abstract modifier indicates that the thing being modified has a missing or incomplete implementation. The abstract modifier can be used with classes, methods, properties, indexers, and events. Use the abstract modifier in a class declaration to indicate that a class is intended only to be a base class of other classes. Members marked as abstract, or included in an abstract class, must be implemented by classes that derive from the abstract class.

 Example
________________________________________
In this example, the class Square must provide an implementation of Area because it derives from ShapesClass:
C#
Copy


abstract class ShapesClass
{
    abstract public int Area();
}
class Square : ShapesClass
{    int side = 0;
    public Square(int n)
    {        side = n;
    }
    // Area method is required to avoid
    // a compile-time error.
    public override int Area()
    {
        return side * side;
    }
    static void Main()
    {
        Square sq = new Square(12);
        Console.WriteLine("Area of the square = {0}", sq.Area());
    }

    interface I
    {
        void M();
    }    abstract class C : I
    {        public abstract void M();
    }
}
// Output: Area of the square = 144


Abstract classes have the following features:

•    An abstract class cannot be instantiated.
•    An abstract class may contain abstract methods and accessors.
•    It is not possible to modify an abstract class with the sealed (C# Reference) modifier because the two modifers have opposite meanings. The sealed modifier prevents a class from being inherited and the abstract modifier requires a class to be inherited.
•    A non-abstract class derived from an abstract class must include actual implementations of all inherited abstract methods and accessors.
Use the abstract modifier in a method or property declaration to indicate that the method or property does not contain implementation.
Abstract methods have the following features:
•    An abstract method is implicitly a virtual method.
•    Abstract method declarations are only permitted in abstract classes.
•    Because an abstract method declaration provides no actual implementation, there is no method body; the method declaration simply ends with a semicolon and there are no curly braces ({ }) following the signature. For example:
public abstract void MyMethod();
The implementation is provided by an overriding methodoverride (C# Reference), which is a member of a non-abstract class.

•    It is an error to use the static or virtual modifiers in an abstract method declaration.
Abstract properties behave like abstract methods, except for the differences in declaration and invocation syntax.
•    It is an error to use the abstract modifier on a static property.
•    An abstract inherited property can be overridden in a derived class by including a property declaration that uses the override modifier.

For more information about abstract classes, see Abstract and Sealed Classes and Class Members (C# Programming Guide) and Abstract Class Design.
An abstract class must provide implementation for all interface members.
An abstract class that implements an interface might map the interface methods onto abstract methods. For example:

interface I
{
    void M();
}
abstract class C : I
{
    public abstract void M();
}
In this example, the class DerivedClass is derived from an abstract class BaseClass. The abstract class contains an abstract method, AbstractMethod, and two abstract properties, X and Y.
    abstract class BaseClass   // Abstract class
    {
        protected int _x = 100;
        protected int _y = 150;
        public abstract void AbstractMethod();   // Abstract method
        public abstract int X    { get; }
        public abstract int Y    { get; }
    }

    class DerivedClass : BaseClass
    {
        public override void AbstractMethod()
        {
            _x++;
            _y++;
        }

        public override int X   // overriding property
        {
            get
            {
                return _x + 10;
            }
        }

        public override int Y   // overriding property
        {
            get
            {
                return _y + 10;
            }
        }

        static void Main()
        {
            DerivedClass o = new DerivedClass();
            o.AbstractMethod();
            Console.WriteLine("x = {0}, y = {1}", o.X, o.Y);
        }
    }
    // Output: x = 111, y = 161
In the preceding example, if you attempt to instantiate the abstract class by using a statement like this:
BaseClass bc = new BaseClass();   // Error
you will get an error saying that the compiler cannot create an instance of the abstract class 'BaseClass'.


Overriding Members
By default, a derived class inherits all members from its base class. If you want to change the behavior of the inherited member, you need to override it. That is, you can define a new implementation of the method, property or event in the derived class.


The following modifiers are used to control how properties and methods are overridden:

      C# Modifier    
      virtual (C# Reference)
Allows a class member to be overridden in a derived class.
      override (C# Reference)
Overrides a virtual (overridable) member defined in the base class.
      Not supported Prevents a member from being overridden in an inheriting class.
      abstract (C# Reference)
Requires that a class member to be overridden in the derived class.
      new Modifier (C# Reference)
Hides a member inherited from a base class




 Interfaces
Interfaces, like classes, define a set of properties, methods, and events. But unlike classes, interfaces do not provide implementation. They are implemented by classes, and defined as separate entities from classes. An interface represents a contract, in that a class that implements an interface must implement every aspect of that interface exactly as it is defined.
To define an interface:
interface ISampleInterface
{
    void doSomething();
}
To implement an interface in a class:
class SampleClass : ISampleInterface
{    void ISampleInterface.SampleMethod()
    {   // Method implementation.   }
}
For more information, see:

•    Interfaces
•    interface

 Generics
________________________________________
Classes, structures, interfaces and methods in the .NET Framework can type parameters that define types of objects that they can store or use. The most common example of generics is a collection, where you can specify the type of objects to be stored in a collection.

To define a generic class:
Public class SampleGeneric<T>
{    public T Field;}
To create an instance of a generic class:
SampleGeneric<string> sampleObject = new SampleGeneric<string>();
sampleObject.Field = "Sample string";
For more information, see:

•    Generics in the .NET Framework
•    Generics (C# Programming Guide)
Generics in the .NET Framework
Generics let you tailor a method, class, structure, or interface to the precise data type it acts upon. For example, instead of using the Hashtable class, which allows keys and values to be of any type, you can use the Dictionary(Of TKey, TValue) generic class and specify the type allowed for the key and the type allowed for the value. Among the benefits of generics are increased code reusability and type safety.
This topic provides an overview of generics in the .NET Framework and a summary of generic types or methods. It contains the following sections:

•    Defining and Using Generics
•    Generics Terminology
•    Class Library and Language Support
•    Nested Types and Generics
•    Related Topics
•    Reference

 Defining and Using Generics
________________________________________
Generics are classes, structures, interfaces, and methods that have placeholders (type parameters) for one or more of the types that they store or use. A generic collection class might use a type parameter as a placeholder for the type of objects that it stores; the type parameters appear as the types of its fields and the parameter types of its methods. A generic method might use its type parameter as the type of its return value or as the type of one of its formal parameters. The following code illustrates a simple generic class definition.
public class Generic<T>
{
    public T Field;
}
When you create an instance of a generic class, you specify the actual types to substitute for the type parameters. This establishes a new generic class, referred to as a constructed generic class, with your chosen types substituted everywhere that the type parameters appear. The result is a type-safe class that is tailored to your choice of types, as the following code illustrates.
public static void Main()
{
    Generic<string> g = new Generic<string>();
    g.Field = "A string";
    //...
    Console.WriteLine("Generic.Field           = \"{0}\"", g.Field);
    Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName);
}

Generics
Generics were added to version 2.0 of the C# language and the common language runtime (CLR). Generics introduce to the .NET Framework the concept of type parameters, which make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code. For example, by using a generic type parameter T you can write a single class that other client code can use without incurring the cost or risk of runtime casts or boxing operations, as shown here:
// Declare the generic class.
public class GenericList<T>
{
    void Add(T input) { }
}
class TestGenericList
{
    private class ExampleClass { }
    static void Main()
    {
        // Declare a list of type int.
        GenericList<int> list1 = new GenericList<int>();
        // Declare a list of type string.
        GenericList<string> list2 = new GenericList<string>();

        // Declare a list of type ExampleClass.
        GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
    }
}

 Generics Overview
________________________________________
•    Use generic types to maximize code reuse, type safety, and performance.
•    The most common use of generics is to create collection classes.
•    The .NET Framework class library contains several new generic collection classes in the System.Collections.Generic namespace. These should be used whenever possible instead of classes such as ArrayList in the System.Collections namespace.
•    You can create your own generic interfaces, classes, methods, events and delegates.
•    Generic classes may be constrained to enable access to methods on particular data types.
•    Information on the types that are used in a generic data type may be obtained at run-time by using reflection

Benefits of Generics
Generics provide the solution to a limitation in earlier versions of the common language runtime and the C# language in which generalization is accomplished by casting types to and from the universal base type Object. By creating a generic class, you can create a collection that is type-safe at compile-time.
The limitations of using non-generic collection classes can be demonstrated by writing a short program that uses the ArrayList collection class from the .NET Framework class library. ArrayList is a highly convenient collection class that can be used without modification to store any reference or value type.

// The .NET Framework 1.1 way to create a list:
System.Collections.ArrayList list1 = new System.Collections.ArrayList();
list1.Add(3);
list1.Add(105);

System.Collections.ArrayList list2 = new System.Collections.ArrayList();
list2.Add("It is raining in Redmond.");
list2.Add("It is snowing in the mountains.");

But this convenience comes at a cost. Any reference or value type that is added to an ArrayList is implicitly upcast to Object. If the items are value types, they must be boxed when they are added to the list, and unboxed when they are retrieved. Both the casting and the boxing and unboxing operations decrease performance; the effect of boxing and unboxing can be very significant in scenarios where you must iterate over large collections.
The other limitation is lack of compile-time type checking; because an ArrayList casts everything to Object, there is no way at compile-time to prevent client code from doing something such as this:
System.Collections.ArrayList list = new System.Collections.ArrayList();
// Add an integer to the list.
list.Add(3);
// Add a string to the list. This will compile, but may cause an error later.
list.Add("It is raining in Redmond.");

int t = 0;
// This causes an InvalidCastException to be returned.
foreach (int x in list)
{
    t += x;
}
Although perfectly acceptable and sometimes intentional if you are creating a heterogeneous collection, combining strings and ints in a single ArrayList is more likely to be a programming error, and this error will not be detected until runtime.
In versions 1.0 and 1.1 of the C# language, you could avoid the dangers of generalized code in the .NET Framework base class library collection classes only by writing your own type specific collections. Of course, because such a class is not reusable for more than one data type, you lose the benefits of generalization, and you have to rewrite the class for each type that will be stored.
What ArrayList and other similar classes really need is a way for client code to specify, on a per-instance basis, the particular data type that they intend to use. That would eliminate the need for the upcast to T:System.Object and would also make it possible for the compiler to do type checking. In other words, ArrayList needs a type parameter. That is exactly what generics provide. In the generic List(Of T) collection, in the N:System.Collections.Generic namespace, the same operation of adding items to the collection resembles this:
// The .NET Framework 2.0 way to create a list
List<int> list1 = new List<int>();

// No boxing, no casting:
list1.Add(3);
// Compile-time error:
// list1.Add("It is raining in Redmond.");
For client code, the only added syntax with List(Of T) compared to ArrayList is the type argument in the declaration and instantiation. In return for this slightly more coding complexity, you can create a list that is not only safer than ArrayList, but also significantly faster, especially when the list items are value types.

 Delegates
________________________________________
A delegate is a type that defines a method signature, and can provide a reference to any method with a compatible signature. You can invoke (or call) the method through the delegate. Delegates are used to pass methods as arguments to other methods.
 Note
Event handlers are nothing more than methods that are invoked through delegates. For more information about using delegates in event handling, see Events and Delegates.
To create a delegate:
public delegate void SampleDelegate(string str);
To create a reference to a method that matches the signature specified by the delegate:
class SampleClass
{    // Method that matches the SampleDelegate signature.
    public static void sampleMethod(string message)
    { // Add code here.}
    // Method that instantiates the delegate.
    void SampleDelegate()
    {   SampleDelegate sd = sampleMethod;
        sd("Sample string");
    }
}

Polymorphism

Through inheritance, a class can be used as more than one type; it can be used as its own type, any base types, or any interface type if it implements interfaces. This is called polymorphism. In C#, every type is polymorphic. Types can be used as their own type or as a Object instance, because any type automatically treats Object as a base type.
Polymorphism is important not only to the derived classes, but to the base classes as well. Anyone using the base class could, in fact, be using an object of the derived class that has been cast to the base class type. Designers of a base class can anticipate the aspects of their base class that are likely to change for a derived type. For example, a base class for cars might contain behavior that is subject to change when the car in question is a minivan or a convertible. A base class can mark those class members as virtual, allowing derived classes representing convertibles and minivans to override that behavior.
For more information, see Inheritance.


What is Polymorphism?
Polymorphism means same operation may behave differently on different classes.
Example of Compile Time Polymorphism: Method Overloading
Example of Run Time Polymorphism: Method Overriding

Example of Compile Time Polymorphism

Method Overloading
- Method with same name but with different arguments is called method overloading.
- Method Overloading forms compile-time polymorphism.
- Example of Method Overloading:
class A1
{
void hello()
{ Console.WriteLine(“Hello”); }

void hello(string s)
{ Console.WriteLine(“Hello {0}”,s); }
}


Example of Run Time Polymorphism

Method Overriding
- Method overriding occurs when child class declares a method that has the same type arguments as a method declared by one of its superclass.
- Method overriding forms Run-time polymorphism.
- Note: By default functions are not virtual in C# and so you need to write “virtual” explicitly. While by default in Java each function are virtual.
- Example of Method Overriding:
Class parent
{
virtual void hello()
{ Console.WriteLine(“Hello from Parent”); }
}

Class child : parent
{
override void hello()
{ Console.WriteLine(“Hello from Child”); }
}

static void main()
{
parent objParent = new child();
objParent.hello();
}
//Output
Hello from Child.


Polymorphism Overview
When a derived class inherits from a base class, it gains all the methods, fields, properties and events of the base class. To change the data and behavior of a base class, you have two choices: you can replace the base member with a new derived member, or you can override a virtual base member.
Replacing a member of a base class with a new derived member requires the new keyword. If a base class defines a method, field, or property, the new keyword is used to create a new definition of that method, field, or property on a derived class. The new keyword is placed before the return type of a class member that is being replaced. For example:
C#
public class BaseClass
{
    public void DoWork() { }
    public int WorkField;
    public int WorkProperty
    {
        get { return 0; }
    }
}

public class DerivedClass : BaseClass
{
    public new void DoWork() { }
    public new int WorkField;
    public new int WorkProperty
    {
        get { return 0; }
    }
}

When the new keyword is used, the new class members are called instead of the base class members that have been replaced. Those base class members are called hidden members. Hidden class members can still be called if an instance of the derived class is cast to an instance of the base class. For example:
C#
DerivedClass B = new DerivedClass();
B.DoWork();  // Calls the new method.

BaseClass A = (BaseClass)B;
A.DoWork();  // Calls the old method.

In order for an instance of a derived class to completely take over a class member from a base class, the base class has to declare that member as virtual. This is accomplished by adding the virtual keyword before the return type of the member. A derived class then has the option of using the override keyword, instead of new, to replace the base class implementation with its own. For example:
C#
public class BaseClass
{
    public virtual void DoWork() { }
    public virtual int WorkProperty
    {
        get { return 0; }
    }
}
public class DerivedClass : BaseClass
{
    public override void DoWork() { }
    public override int WorkProperty
    {
        get { return 0; }
    }
}

Fields cannot be virtual; only methods, properties, events and indexers can be virtual. When a derived class overrides a virtual member, that member is called even when an instance of that class is being accessed as an instance of the base class. For example:
C#
DerivedClass B = new DerivedClass();
B.DoWork();  // Calls the new method.

BaseClass A = (BaseClass)B;
A.DoWork();  // Also calls the new method.

Virtual methods and properties allow you to plan ahead for future expansion. Because a virtual member is called regardless of which type the caller is using, it gives derived classes the option to completely change the apparent behavior of the base class.
Virtual members remain virtual indefinitely, no matter how many classes have been declared between the class that originally declared the virtual member. If class A declares a virtual member, and class B derives from A, and class C derives from B, class C inherits the virtual member, and has the option to override it, regardless of whether class B declared an override for that member. For example:
C#
public class A
{
    public virtual void DoWork() { }
}
public class B : A
{
    public override void DoWork() { }
}

C#
public class C : B
{
    public override void DoWork() { }
}

A derived class can stop virtual inheritance by declaring an override as sealed. This requires putting the sealed keyword before the override keyword in the class member declaration. For example:
C#
public class C : B
{
    public sealed override void DoWork() { }
}

In the previous example, the method DoWork is no longer virtual to any class derived from C. It is still virtual for instances of C, even if they are cast to type B or type A. Sealed methods can be replaced by derived classes using the new keyword, as the following example shows:
C#
public class D : C
{
    public new void DoWork() { }
}

In this case, if DoWork is called on D using a variable of type D, the new DoWork is called. If a variable of type C, B, or A is used to access an instance of D, a call to DoWork will follow the rules of virtual inheritance, routing those calls to the implementation of DoWork on class C.
A derived class that has replaced or overridden a method or property can still access the method or property on the base class using the base keyword. For example:
C#
public class A
{
    public virtual void DoWork() { }
}
public class B : A
{
    public override void DoWork() { }
}

C#
public class C : B
{
    public override void DoWork()
    {
        // Call DoWork on B to get B's behavior:
        base.DoWork();

        // DoWork behavior specific to C goes here:
        // ...
    }
}

There are two types of polymorphism
1.runtime
2.compiletime

to achieve the runtime polymorphism there are three ways
1.Function overloading
2.Operator Overloading
3.Constructor Overloading


When a message can be processed in different ways is called polymorphism. Polymorphism means many forms.

Polymorphism is one of the fundamental concepts of OOP.

Polymorphism provides following features:

•    It allows you to invoke methods of derived class through base class reference during runtime.
•    It has the ability for classes to provide different implementations of methods that are called through the same name.

Polymorphism is of two types:

1.   Compile time polymorphism/Overloading
2.   Runtime polymorphism/Overriding

Compile Time Polymorphism

Compile time polymorphism is method and operators overloading. It is also called early binding.

In method overloading method performs the different task at the different input parameters.

Runtime Time Polymorphism

Runtime time polymorphism is done using inheritance and virtual functions. Method overriding is called runtime polymorphism. It is also called late binding.

When overriding a method, you change the behavior of the method for the derived class.  Overloading a method simply involves having another method with the same prototype.

Caution: Don't confused method overloading with method overriding, they are different, unrelated concepts. But they sound similar.

Method overloading has nothing to do with inheritance or virtual methods.

Following are examples of methods having different overloads:

void area(int side);
void area(int l, int b);
void area(float radius);

Practical example of Method Overloading (Compile Time Polymorphism)

using System;

namespace method_overloading
{
    class Program
    {
        public class Print
        {
          
            public void display(string name)
            {
                Console.WriteLine("Your name is : " + name);
            }

            public void display(int age, float marks)
            {
                Console.WriteLine("Your age is : " + age);
                Console.WriteLine("Your marks are :" + marks);
            }
        }
      
        static void Main(string[] args)
        {

            Print obj = new Print();
            obj.display("George");
            obj.display(34, 76.50f);
            Console.ReadLine();
        }
    }
}

Note: In the code if you observe display method is called two times. Display method will work according to the number of parameters and type of parameters.


When and why to use method overloading

Use method overloading in situation where you want a class to be able to do something, but there is more than one possibility for what information is supplied to the method that carries out the task.

You should consider overloading a method when you for some reason need a couple of methods that take different parameters, but conceptually do the same thing.

Method Overloading showing many forms.

using System;

namespace method_overloading_polymorphism
{
    class Program
    {
        public class Shape
        {
            public void Area(float r)
            {
                float a = (float)3.14 * r;
                // here we have used funtion overload with 1 parameter.
                Console.WriteLine("Area of a circle: {0}",a);
            }

            public void Area(float l, float b)
            {
                float x = (float)l* b;
                // here we have used funtion overload with 2 parameters.
                Console.WriteLine("Area of a rectangle: {0}",x);

            }

            public void Area(float a, float b, float c)
            {
                float s = (float)(a*b*c)/2;
                // here we have used funtion overload with 3 parameters.
                Console.WriteLine("Area of a circle: {0}", s);
            }
        }

        static void Main(string[] args)
        {
            Shape ob = new Shape();
            ob.Area(2.0f);
            ob.Area(20.0f,30.0f);
            ob.Area(2.0f,3.0f,4.0f);
            Console.ReadLine();
        }
    }
}

Things to keep in mind while method overloading

If you use overload for method, there are couple of restrictions that the compiler imposes.

The rule is that overloads must be different in their signature, which means the name and the number and type of parameters.

There is no limit to how many overload of a method you can have. You simply declare them in a class, just as if they were different methods that happened to have the same name.


Difference between Struct and Class

Struct are Value type and are stored on stack, while Class are Reference type and are stored on heap.

Struct “do not support” inheritance, while class supports inheritance. However struct can implements interface.

Struct should be used when you want to use a small data structure, while Class is better choice for complex data structure.


No comments: