Trying to illustrate some important features and syntax of C# with examples.
Var This is used to declare implicitly typed local variable. Which tells the compiler to identify the type at the time of compilation. This is introduced in C# 3.0 and must be initialized at the time of declaration. The value of a var variable cannot be NULL at compile time but can be NULL at run time. Once the value of var variable is initialized its data type is fixed to the initial data.
Definition |
Compile Time |
var testString = "Testing String data type"; |
string testString = "Testing String data type"; |
var testInteger = 123; |
int testInteger = 123; |
string test = "String data type"; var testString2 = test; |
string test = test; |
Anonymous Types
This is a class generated by compiler within IL to store values. Using VAR and NEW, these anonymous types can be created. These types are very handy when one wants to return the results in a desired form. Below is an example of an anonymous type:
var employee = new { FirstName = "Balaji", LastName = "Telugunti", Salary = 200000 };
Anonymous Methods
An anonymous method is an inline method within C# code with no name. In other terms, an anonymous method will have only body with optional parameters and return type. This behaves just like any other regular method and will be created using delegate keyword. This concept was introduced from C# 2.0 version. Below are some key points about anonymous methods:
- Variables declared outside of an anonymous method can be accessed in an anonymous method, but variables declared within anonymous methods cannot be accessed from
outside of the method
- These methods are used as part of event handling
- A method without parenthesis can be assigned to a delegate
- An anonymous method cannot access the ref or out parameters from an outer scope
Lamda Expressions A new way to write anonymous methods is lamda expression. These are introduced in C# 3.0. These expressions will be converted into anonymous methods at compile time using lamda expression conversion rules which is, The left of the lamda operator => represents arguments and right side is the method body. Below are the features of lamda expression:
- Do not have a type
- Cannot be assigned to an implicitly typed local variable since these expressions do not have type
- Jump statements are not allowed within anonymous method/lamda expression
- Variables declared within these expressions are accessible only within the scope of the body
- These are used generally with the Func and Action delegates
Extension Methods Conceptually this is the implementation of decorator structural pattern and at compile time these extension method calls will be translated into an ordinary static method calls. By definition, an extension method is a static method of a static class that can be invoked using the instance method. These are used to add new behavior of an existing type without altering the original behavior.
Delegates Delegate is a reference type that holds the reference of a class method. Any method which has the same signature as delegate can be assigned to delegate. These are immutable in nature, so when you call += or -=, a new delegate instance is created and it assigns to the existing delegate instance. All Delegates are implicitly derived from System.MulticastDelegate, class which is inherit from System.Delegate class. Delegates types are all incompatible with each other, even if their signatures are the same. Delegate instances are considered equal if they have the reference of same method. Delegate instances are considered equal if they have the reference of same method. Multicast delegates are considered equal if they reference the same methods in the same order. And, Delegates are used in event handling.
Type Casting
Is a mechanism of converting one data type to another data type. During this process, if the data types are not compatible then the compiler will throw the exception. C# provides IS and AS operators to handle this exception and handles the type casting without any issues. Below is the explanation of both the operators:
IS The IS operator helps to check whether the type of a given object is compatible with the new object type. Returns boolean value TRUE if the given object is compatible, if not returns FALSE. If the reference of the given object is NULL, then this will return FALSE as there is not object available to check its type.
The one drawback of using IS operator is, it will hit the performance since every time CLR will check base type against the specified type.
AS This AS operator also checks whether the given type object is compatible with the new object type or not. This actually return NON-NULL when both objects are compatible, and NULL in case when the objects are not compatible. If the reference of the given object is NULL, then this operator will return NULL since there is not object to check the type. This operator performs only reference conversions, nullable conversions, and boxing conversions. This cannot perform other conversions like user defined conversions.
This check the object only one time, as a result of that performance improves.
Interfaces
Typically, an interface exposes it's members to a group of clients which needs to use common functionalities. These mainly acts as contract(s) between itself and any class / struct which implements it.
Features
- An interface just defines member of it and the implementation class/struct needs to implement the functionality
- Interface can be referenced but cannot be instantiated
- Contains properties, indexers, methods, delegates and event definitions
- Cannot contain constants, members, constructors, instance variables, destructors, static members or nested interfaces
- Cannot have access modifiers as part of definition even public
- An interface can be inherited from one or more interfaces and can extend another interface
- A class which implements an interface can mark any method as virtual to make that method overridden by the derived class
Advantages
- To provide common functionality to unrelated classes
- To group objects based on common behaviors, to support polymorphism feature of OOP
- To create loosely couple components, easily maintainable and to support Separation of Concerns
Disadvantages
- Interfaces are slow as they require extra time to find corresponding method in the actual class
- When you add new members to it, then they must implement those members in all of the implemented classes or structs
Abstract Class
These classes are special type of classes which cannot be instantiated but can be base for other classes. Any of the methods which are marked as Abstract must be implemented by the derived class. Main purpose of this class is to provide basic or default functionality as well as common functionality that multiple derived classes can share and override. These are helpful as versioning is not a problem for abstract classes. New Properties or Methods can be added without breaking the code as all inheriting classes will be updated automatically.
Don't define public constructors within abstract class. Since abstract class cannot be instantiate and constructors with public access modifiers provides visibility to the classes which can be instantiated. Define a protected or internal constructor within an abstract class.
- An Abstract class cannot be instantiated. Contains both abstract and non-abstract members
- An Abstract class cannot be sealed as it restricts from being inherited
- An Abstract class can be inherited brom a class, one or more interfaces and cannot support multiple inheritance
Errors and Exception Handling
Errors refer to the mistake or faults which occur during program development or execution. Different types of errors are:
Syntax Errors: These occur during development when you type mistakes in code
Runtime Errors: These occur during execution of the program which are also called exceptions. Can cause because of improper inputs or design logic. These can be handled by try-catch blocks
Logical Errors: These errors occur when the program does not produce desired result. These are difficult to find as one need to investigate where the result
went wrong.
Exception handling is a mechanism to detect and handle run time errors. Using Try-Catch-Finally blocks and Throw keywords one can take care of exception handling
With this I am concluding the illustration. Feel free to share your feedback.
Happy Programming !!!