Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Polymorphism in C#

Polymorphism is the ability of an object oriented language (C# in this context) to allow a base class to define a set of members (formally termed the polymorphic interface) that are available to all descendents. A class’s polymorphic interface is constructed using any number of virtual or abstract members.

A virtual member is a member in a base class that defines a default implementation that may be changed (overridden) by a derived class.

In contrast, an abstract method is a member in a base class that does not provide a default implementation, but does provide a signature. When a class derives from a base class defining an abstract method, it must be overridden by a derived type.

In either case (virtual or abstract), when derived types override the members defined by a base class, they are essentially redefining how they respond to the same request.

Method Overriding – Method Overriding is a process in which a derived class can define its own version of a method, which was originally defined by its base class.

Virtual Keyword – The virtual keyword indicates that the base class wants to define a method which may be (but does not have to be) overridden by a derived class. A virtual method provides a default implementation that all derived types automatically inherit. If a child class so chooses, it may override the method but does not have to.

Note: Subclasses are never required to override virtual methods.

Override Keyword – The override keyword is used by a derived class to to change the implementation details of a virtual method (defined in the base class). Each overridden method is free to leverage the default behavior of the parent class using the base keyword.

Sealed Keyword – The sealed keyword is basically applied to classes to prevent other types from extending its behavior via inheritance.

It can also be applied to virtual methods to prevent derived types from overriding those methods. Ex.

public override sealed void GiveBonus(float amount)
{
...
}

Any effort to override the above sealed method in the derived class will generate compile time error.

Abstract Classes – The abstract keyword can be used in the class definition to prevent direct creation of an instance of the class. Although abstract classes cannot be created directly, it is still assembled in memory when derived classes are created. Thus, it is perfectly fine for abstract classes to define any number of constructors that are called indirectly when derived classes are allocated.

An abstract class can define any number of abstract members (members that does not supply a default implementation, but must be accounted for by each derived class).

The polymorphic interface of an abstract base class simply refers to its set of virtual and abstract methods. Methods marked with abstract are pure protocol. They simply define the name, return type (if any), and parameter set (if required).

If you do not override an abstract method (of the base abstract class) in the derived class, the derived class will also be considered abstract, and would have to be marked abstract with the abstract keyword.

Although it is not possible to directly create an instance of an abstract base class, you can freely store references to any subclass with an abstract base variable.

Q: What is an efficient way to force each child class to override a virtual method?

A: To force each child class to override a virtual method, we can better define an abstract method (which by definition means you provide no default implementation whatsoever), in an abstract class.

Inheritance in C#

Inheritance is the ability of an object oriented language (C# in this context) to build new class definitions based on existing class definitions. Inheritance allows us to extend the behavior of a base (parent) class by inheriting core functionality into the derived subclass (child class). Inheritance promotes code re-usability.

Inheritance preserves encapsulation – private members of the base class can never be accessed from an object reference of the derived class. Private members can only be accessed by the class that defines it.

C# does not support Multiple Inheritance. A class in C# cannot directly derive from two or more base classes.

Encapsulation in C#

Encapsulation is the ability of an object oriented language (C# in this context) to hide unnecessary implementation details from the object user. Encapsulation makes coding simpler and helps to preserve data integrity.

According to the concept of encapsulation, an object’s internal data should not be directly accessible from an object instance. Members of a class that represent an object’s state should not be marked as public. The state of an object should only be altered indirectly by using public members. C# prefers properties to encapsulate data. Ex.

class ABC
{
// private data members
private int roll;
private int class;
private string name;

// public properties
public int Roll
{
get { return roll; }
set { roll = value; }
}
public int Class
{
get { return class; }
set { class = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}

// constructor
public ABC()
{
// values are assigned to data members via properties
Roll = 10;
Class = 9;
Name = “Rajveer Raj Banti”;
}
}

Evolution of C# (1.0 – 5.0)

C# is a multi-paradigm (structured, imperative, object-oriented, event-driven, functional, generic, reflective, concurrent) programming language. It was developed within Microsoft. The development team which consisted of Scott Wiltamuth, Peter Golde and others was led by Anders Hejlsberg.

The first version of C# was released by Microsoft in July 2000. The latest version of C# is 5.0, which was released on August 15, 2012.

C# 1.0

C# 1.0 was released by Microsoft with Visual Studio 2002. C# 1.0 targets .NET Framework 1.0. It was the first language adopted by developers to build .NET applications.

C# 1.2

C# 1.2 was released by Microsoft with Visual Studio 2003. C# 1.2 targets .NET Framework 1.1.

C# 2.0

C# 2.0 was released by Microsoft with Visual Studio 2005. C# 2.0 targets .NET Framework 2.0.
The new features added in C# 2.0 are as given below:
  • Generics
  • Partial types
  • Anonymous methods
  • Iterators
  • Nullable types
  • Private setters (properties)
  • Method group conversions (delegates)
  • Covariance and Contravariance
C# 3.0

C# 3.0 was released by Microsoft with Visual Studio 2008. It is also compatible with Visual Studio 2010. C# 3.0 targets the .NET Framework 2.0 (Except LINQ/Query Extensions), .NET Framework 3.0 (Except LINQ/Query Extensions) and .NET Framework 3.5.
The new features added in C# 3.0 are as given below:
  • Implicitly typed local variables (var)
  • Object and collection initializers
  • Auto-Implemented properties
  • Anonymous types
  • Extension methods
  • Query expressions
  • Lambda expressions
  • Expression trees
  • Partial Methods
  • LINQ
C# 4.0

C# 4.0 was released by Microsoft with Visual Studio 2010. C# 4.0 targets .NET Framework 4.0.
The new features added in C# 4.0 are as given below:
  • Dynamic binding (Late binding)
  • Named and optional arguments
  • Generic Covariance and Contravariance
  • Embedded interop types ("NoPIA")
C# 5.0

C# 5.0 was released by Microsoft with Visual Studio 2012. C# 5.0 targets .NET Framework 4.5.
The new features added in C# 4.0 are as given below:
  • Asynchronous methods
  • Caller info attributes
Future

The upcoming versions of C# might include the following features:
  • Compiler-as-a-service ("Roslyn")
The Evolution of C# programming language

Casting and Reference Conversions – Differentiate between Upcasting and Downcasting

An object reference can be:
  • Implicitly upcast to a base class reference
  • Explicitly downcast to a subclass reference
Upcasting and downcasting between compatible reference types performs reference conversions: a new reference is (logically) created that points to the same object. 
An upcast always succeeds; a downcast succeeds only if the object is suitably typed.

Upcasting

An upcast operation creates a base class reference from a subclass reference. For example:

Vechicle oVechicle = new Vechicle();
Car oCar = oVechicle; // Upcast

After the upcast, variable oCar still references the same Vechicle object as variable oVechicle. The object being referenced is not itself altered or converted:

Console.WriteLine (oCar == oVechicle); // True

Although oCar and oVechicle refer to the identical object, oCar has a more restrictive view on that object:

Console.WriteLine (oCar.Name); // OK
Console.WriteLine (oCar.VechicleCount); // Error: VechicleCount undefined

The last line generates a compile-time error because the variable oCar is of type Car, even though it refers to an object of type Vechicle. To get to its VechicleCount field, you must downcast the Vechicle to a Car.

Downcasting

A downcast operation creates a subclass reference from a base class reference. For example:

Vechicle oVechicle = new Vechicle();
Car oCar = oVechicle; // Upcast

Vechicle oVechicle1 = (Vechicle)oCar; // Downcast
Console.WriteLine (oVechicle1.VechicleCount); // <No error>
Console.WriteLine (oVechicle1 == oCar); // True
Console.WriteLine (oVechicle1 == oVechicle); // True

As with an upcast, only references are affected—not the underlying object. A downcast requires an explicit cast because it can potentially fail at runtime:

Maruti oMaruti = new Maruti();
Car oCar = oMaruti; // Upcast always succeeds
Vechicle oVechicle = (Vechicle)oCar; // Downcast fails: oCar is not a Car

If a downcast fails, an InvalidCastException is thrown. This is an example of runtime type checking.

Explain the IEnumerable Interface

Namespace – System.Collections
Assembly mscorlib (in mscorlib.dll)

IEnumerable Interface is the base interface for all non-generic collections that can be enumerated. It exposes an enumerator, which supports a simple iteration over a non-generic collection. System.Collections.Generic.IEnumerable<T> is the generic version of this interface.

IEnumerable contains a single method, GetEnumerator, which returns an IEnumerator which provides the ability to iterate through the collection by exposing a Current property and MoveNext and Reset methods.

Implementation of IEnumerable and IEnumerator on collection classes enables the foreach syntax on a collection. The members of these interfaces are not explicitly called, but they are implemented to support the use of foreach to iterate through the collection.

Static Constructors - What is the output of the C# code?

class A
{
  public A(string text)
  {
    Console.WriteLine(text);
  }
}

class B
{
  static A a1 = new A("a1");

  A a2 = new A("a2");

  static B()
  {
    a1 = new A("a3");
  }

  public B()
  {
    a2 = new A("a4");
  }
}

class Program
{
  static void Main(string[] args)
  {
    B b = new B();
  }

}

Before any code of the type B gets executed, its static constructor will be invoked first. It initializes static data fields and then executes statements inside the static constructor. Therefore, it prints a line of “a1”, and then another line of “a3”.

When the execution flow reaches the statement B b = new B(), the ordinary constructor is invoked. It initializes its data fields first and then the statements in its constructor method, so it prints a line of “a2”, and then another line of “a4”.

Output:

a1
a3
a2
a4

Access Modifiers in C#

Access Modifiers are used to control the visibility of a type (classes, interfaces, structures, enumerations, and delegates) or their members (properties, methods, constructors, and fields) to other parts of an application.

Role of each access modifier and where it may be applied:

Access Modifier Applicable to Description
public Types or type members Public items have no access restrictions. A public member can be accessed from an object, as well as any derived class. It can also be accessed from other external assemblies.
private Type members or nested types Private items can only be accessed by the class (or structure) that defines the item.
protected Type members or nested types Protected items can be used by the class which defines it, and any child class. However, protected items cannot be accessed from the outside world using the C# dot operator.
internal Type or type members Internal items are accessible only within the current assembly. Therefore, if you define a set of internal types within a .NET class library, other assemblies are not able to make use of them.
protected internal Type members or nested types
When the protected and internal keywords are combined on an item, the item is accessible within the defining assembly, the defining class, and by derived classes.

Note: By default, type members (ex. members of a class) are implicitly private while types (ex. classes) are implicitly internal.

// An internal class with a private default constructor.
class Country
{
// default constructor – implicitly private
Country()
{
}
}

Note: Nested types can have private access, but non-nested types cannot be marked private.

public class Country
{
// OK! Nested types can be marked private.
private enum FlagColor
{
Red, Green, Blue
}
}

Here, it is permissible to apply the private access modifier on the nested type. However, non-nested types (such as the Country) can only be defined with the public or internal modifiers.

// Error! Nonnested types cannot be marked private!
private class Country
{}

static keyword in C#

When a class member is prefixed by a static keyword, it becomes a static member, and it must be invoked directly from the class level, rather than from an object reference variable. Static members promote a given item to the class level rather than the object level. Static data is allocated once and shared among all instances of the class. The CLR allocates the static data into memory exactly one time.

While any class can define static members, they are quite commonly found within utility classes. By definition, a utility class is a class that only exposes static functionality. It does not maintain any object-level state and is not created with the new keyword.
Rather, a utility class exposes all functionality as class-level (a.k.a., static) members.

The static keyword can be applied to data members, methods, properties, constructor, and entire class definition.

Note: this keyword cannot be used with a static member because this implies an object. A static member cannot reference non-static members in its implementation (it will generate a compiler error).

Q: What will happen if you attempt to assign the value of a static data member in a typical (non-static or instance level) constructor?

A: The the value of the static data member will be reset each time you create a new object.

Static Constructor: A static constructor is a special constructor that is an ideal place to initialize the values of static data when the value is not known at compile time (e.g., read in the value from an external file, a database, generate a random number, etc).

A static constructor allows us to initialize static members of a class at runtime. The CLR calls all static constructors before first use (and never calls them again for that instance of the application).

Few interesting points regarding static constructors:
  1. A given class can define only one static constructor. The static constructor cannot be overloaded.
  2. A static constructor does not take an access modifier and cannot take any parameters.
  3. A static constructor executes exactly one time, regardless of how many objects of the type are created.
  4. The runtime invokes the static constructor when it creates an instance of the class or before accessing the first static member invoked by the caller.
  5. A static constructor cannot be called directly through the code.
  6. The static constructor executes before any instance-level constructors.
Static Class: A static class cannot be created using the new keyword (i.e; it cannot have an instance or object). It can contain only static members (static data members, static methods, static properties or a static constructor).

How to keep a local variable in scope across a try and catch block

The following code is erroneous, and won't work, because oSqlConnection goes out of scope before you enter the catch block.

try
{
SqlConnection oSqlConnection = new SqlConnection();
oSqlConnection.Open();
}
catch
{
if (oSqlConnection != null) oSqlConnection.Close();
}

Fix for the IssueThe fix is simple - just declare oSqlConnection before entering the try block.

SqlConnection oSqlConnection = null; // Note the assignment to null to avoid error CS0165 - Use of possibly unassigned local variable 'oSqlConnection'.

try
{
oSqlConnection = new SqlConnection();
oSqlConnection.Open();
}
catch
{
if (oSqlConnection != null) oSqlConnection.Close();
}

For this particular example, you could wrap the SqlConnection class in one that implements IDisposable (if it does not already), so that you could then use a using statement instead of extending the scope of the local.

Static Constructors

A static constructor is invoked automatically before the first instance of the class is created or any static members are referenced. It initializes static data members when the class is referenced first time.

Why is a static constructor used?
  • A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only.
  • Typical use of static constructors – When the class is using a log file, the static constructor can be used to write entries to the log file.
  • Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.

Properties of static constructors
  • A static constructor does not take access modifiers or have parameters.
  • The execution of a static constructor is triggered automatically when the first instance of the class is created or any static members are referenced.
  • A static constructor cannot be called directly.
  • The user has no control on the execution of static constructor.

Example: In this example, the class Bus has a static constructor and one static member, Drive(). When Drive() is called, the static constructor is invoked to initialize the class.

public class Bus
{
    // Static constructor:
    static Bus()
    {
        System.Console.WriteLine("The static constructor invoked.");
    }

    public static void Drive()
    {
        System.Console.WriteLine("The Drive method invoked.");
    }
}

class TestBus
{
    static void Main()
    {
        Bus.Drive();
    }
}

Output:  
The static constructor invoked.
The Drive method invoked.

What are Special (Specialized) Collections in .Net?

The System.Collections.Specialized namespace contains specialized and strongly-typed collections. Specialized Collections are the customized .Net collection classes which are used for specific purposes.

Four most important special collection classes which are commonly used are as follows:
  1. CollectionsUtil – CollectionsUtil class helps to Creates collections that ignore the case in strings. The methods of the CollectionsUtil class generate a case-insensitive instance of the collection using case-insensitive implementations of the hash code provider and the comparer. The resulting instance can be used like any other instances of that class, although it may behave differently.
    Example:
Hashtable ObjHash = CollectionsUtil.CreateCaseInsensitiveHashtable();
ObjHash.Add("mohan","he is a software developer");
string str = (string) ObjHash["MOHAN"];
MessageBox.Show(str);
  1. ListDictionary – ListDictionary implements IDictionary by using a singly linked list. It is smaller and faster than a Hashtable if the number of elements is 10 or less. So, it is recommended for collections that typically contain 10 items or less.
    Example:
ListDictionary ObjDic = new ListDictionary();
ObjDic.Add("manoj", "he is a software developer");
ObjDic.Add("ramesh", "he is a software developer");
  1. HybridDictionary – HybridDictionary implements IDictionary by using a ListDictionary while the collection is small, and then switching to a Hashtable when the collection gets large. It should be used in cases where the number of elements in a dictionary is unknown.
    If the initial size of the collection is greater than the optimal size for a ListDictionary, the collection is stored in a Hashtable right away to avoid the overhead of copying elements from the ListDictionary to a Hashtable.
    Example:
HybridDictionary ObjHybrid = new HybridDictionary();
ObjHybrid.Add("mohan", "he is a software developer");
ObjDic.Add("Raja", "he is a network administrator");
ObjDic.Add("ramesh", "he is a hardware engineer");
  1. StringCollection – StringCollection is a very special collection, which represents a collection of strings. StringCollection accepts a null reference (Nothing in Visual Basic) as a valid value and allows duplicate elements. String comparisons are case-sensitive. Indexes in this collection are zero-based.
    Example:
    
    // Creates and initializes a new StringCollection.
    StringCollection myCol = new StringCollection();
    
    // Adds a range of elements from an array to the end of the StringCollection.
    String[] myArr = new String[] { "RED", "orange", "yellow", "RED", "green", "blue", "RED", "indigo", "violet", "RED" };
    myCol.AddRange( myArr );
    
    // Adds one element to the end of the StringCollection and inserts another at index 3.
    myCol.Add( "* white" );
    myCol.Insert( 3, "* gray" );
    
    // Removes one element from the StringCollection.
    myCol.Remove( "yellow" );
    
    // Clears the entire collection.
    myCol.Clear();

Value Types Vs. Reference Types

There are two kinds of types in C#: Value types and Reference types.

Value Types

  • Variables of value types directly contain their data in memory allocated on the stack.
  • Storage of contents of a variable in a stack increases efficiency, but the limited lifetime of value types makes them in-efficient for sharing data between different classes.
  • With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other (except in the case of ref and out parameter variables).
  • When a value type variable goes out of scope, the value is discarded from the stack.
  • C#’s value types are further divided into simple types, enum types, struct types (even if their members are reference types), and nullable types.
  • Value types are derived from System.ValueType.
  • When value types are passed By Value, the actual value is copied and there are no references involved. When value types are passed By Reference, the method argument is initialized with the address pointing back to the original value in the calling routine.

Example

class Program
{
static void Main(string[] args)
{
int iMarksOfRam = 65;
int iMarksOfTom = iMarksOfRam;
iMarksOfRam++; //
Console.WriteLine(iMarksOfTom); // it will display 65, iMarksOfRam++ won’t affect on iMarksOfTom
Console.WriteLine(iMarksOfRam); // it will display 66
Console.Read();
}
}

Reference Types

  • Variables of reference types store references to their data (known as objects) on the heap.
  • Declaration of reference types has a greater overhead, but they are accessible from other classes, which is a clear advantage.
  • With reference types, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable.
  • When a reference type variable goes out of scope, the memory is not returned to the heap. Instead, it is reclaimed by the garbage collector when it determines that the variable is no longer needed.
  • C#’s reference types are further divided into class types, interface types, array types (even if their elements are value types), and delegate types.
  • Reference types are derived from System.Object.
  • 90% of the time, when reference types are passed By Value or By Reference, it is functionally the same. However, in horns of dilemma, pass reference types By Value and not By Reference!

Note: When a value type is passed by reference, it simply points back to the original value type. However, when a reference type is passed by value, it creates a copy of the reference (address) inside the method being invoked.

Example

class Program
{
static void Main(string[] args)
{
StringBuilder sReferenceTypeX = new StringBuilder("Hello ");
StringBuilder sReferenceTypeY = sReferenceTypeX;
sReferenceTypeX.Append("World");
Console.WriteLine(sReferenceTypeY); //it will display Hello World
Console.WriteLine(sReferenceTypeX); //it will display Hello World
Console.Read();
}
}