|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
IntroductionIn this article I will get a close eye on the concepts of Generics (introduced in C# 2.0) and Extension Methods (Introduced in C# 3.0), and how to mix both concepts together to get a new concept of Generic Extension Methods that will make a difference in our class Desgins. BackgroundThis article is talking about two concepts merged together: Generics and Extension Methods, so in order to understand it you got to be familiar with both concepts, so I am going to summarize on each one. Generics are a new feature in C# 2.0 and the common language runtime which introduces the concept of type parameters, so you can just specify your type for a class or a method at runtime. Extension methods are a new feature in C# 3.0 and the common language runtime in which allows existing classes to use extra methods (extension methods) without being implemented in the same class or got by inheritence. Generics SampleBelow is a sample of using generics with methods, the same concept apply to classes, but for the purposes of this article we are gonna use a generic method: public class SomeClass
{
///Using of one type as parameter
public string Method1<TInput>(TInput obj1)
{
//return a serialized object as string for example
}
///Using of two types as parameters
public TReturn Method2<TReturn, TInput>(TInput obj1)
{
//map data from an instance of TInput type to TReturn type and return an
//instance of TReturn type
}
///Using of three types as parameters
public TReturn Method3<TReturn, TInput1, TInput2>(TInput1 obj1, TInput2 obj2)
{
//Map data from an instance of TInput1 and TInput2 types to an
//instance of TReturn type and return that instance
}
}
Fairly Simple, for a certian method you declare types before the () and use them as your input or output or both or even inside the method body without being used as Input or Output. Extension Methods SampleBelow is a sample of using extension methods public class MyClass{
private string m_Name;
public string Name{
get{return m_Name;}
set{m_Name=value;}
}
}
public ExtensionMethodsClass{
public static string DoSerialize(this MyClass entity){
//Serialze the entity object and return its string represenatation
}
}
Note the use of MyClass instance=new MyClass();
instance.DoSerialize();
Although that the The input parameter of the Pretty ... ha ! ... now lets take a look on how to merge the two concepts together, its fabulous actually ;) Generic Extension MethodAs we have seen earlier, the public ExtensionMethodsClass{
public static string DoSerialize<T>(this T entity){
//Serialze the entity object and return its string represenatation
}
}
Up to here, any type will use this extension method to make a serialization using the Using the 'Where' Clause with GenericsHere comes the role of the public ExtensionMethodsClass{
public static string DoSerialize<T>(this T entity) where T: MyClass{
//Serialze the entity object and return its string represenatation
}
}
Using the above code we determined that the generic type used should be of type public static string DoSerialize(this MyClass entity){ ...}
which we wanted to expand from the whole begining ! so how can we get it all together ?! When and How to Use it ? and the effect on DesignUsually we have an application, we have alot of business classes in it, most probably we have that base class or interface for all these business classes, and common behaviours are replaced within that class or interface, now these behaviours should be only implemented for our business entities, and not any other .net classes for example, so we have two options:
Both solutions will do the trick for you, but it will affect your design on the long run, you see, inheritence had always tied our code with its limitations, its not that this is a bad thing, its just the way inheritence work, and sometimes solving problems using inheritence will lead to major problems in the design then to maintenance problems in happey cases, so you got to be carefull doing so, in the other hand, Generic Extension Methods will make us avoid those limitations by Inheritence because its expandable, lets take a look at the following code which will illustrate a good example of Generic Extension Methods and helping in the design as well: public class BaseClass{
}
public class MyClass: BaseClass, ISerializable{
}
public class YourClass: BaseClass, ISerializable{
}
public class HisClass: ISerializable{
}
public class HerClass: ISerializable{
}
public ExtensionMethodsClass{
public static string DoSerialize<T>(this T entity) where T: BaseClass{
//Serialze the entity object and return its string represenatation
}
}
As we can see in the above code, we have four ordinary classes and an ExtensionMethods Class, the four classes are serializable, the classes But in this context, a member here in code project notated how using: public static string DoSerialize<T>(this T entity) where T: BaseClass { ...}
will be different from using : public static string DoSerialize(this BaseClass entity){ ...}
Actually in this context it wont be much of a difference... but lets take a look to the flexibility we could have by using the following example: //Our Interfaces
public interface IFirstInterface
{
}
public interface ISecondInterface
{
}
//Our Classes
public class AClass : IFirstInterface
{
}
public class BClass : ISecondInterface
{
}
public class CClass: IFirstInterface , ISecondInterface
{
}
//Our Extension Methods Class
public static class ExtensionMethodsClass
{
public static void DoSerialize<T>(this T entity)
where T: IFirstInterface, ISecondInterface
{
}
}
I think the code is obevious enough to explain it self :) ... simply an instance of AClass A=new AClass();
BClass B=new BClass();
CClass C=new CClass();
A.DoSerialize();//Compiler Error
B.DoSerialize();//Compiler Error
C.DoSerialize();//Works Fine
ConclusionGenerics and extension methods are two great concepts in which they really help in our design of classes, they help us in minimizing our code and use the concept of Code Refactoring, in the addetion maintenance will be always much easier using extension methods, but I think we should always keep an eye on the fact that our design demands will control what technologies we should use, not the other way around, but understanding our technologies will help us more in taking our major decisions in our designs ! History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||