Tuesday, August 16, 2011

Using Generic Type variables as method arguments

Let me start with some theories before a practical scenario. We have base class named MyGenBase inherited from object which accept a generic variable and contains some Properties and there are many derived classes which are not generic.There is also a static method named Process() which needs to accept the base class as it is and manipulate the properties.ie the objects of derived classes will be coming into the Process() as arguments.So how to write the signature of the Process().If we simply use Process(proxy as MyGenBase(of T)) it cannot accept the generic variable  T.If we normally use just T as generic variable it cannot access the variables of MyGenBase.So the solution is to use the generic variable with constraint as follows.

Process(of T)(proxy as MyGenBase(of T)) .

Confused altogether? Sorry I am little bit weak in theory. Lets see a real life example.

Using ClientBase<T> as method arguement

This is about passing a ClientBase<T> type variable as method parameter. ClientBase<T> is a well known class and you might have  used or at least heard, if you have did anything in WCF.

Suppose if we have to add a particular behavior to the proxies which are created at the client side of our application based on some conditions we cannot use the application config files for sure.The only way left is add the behavior through code.For Eg:

Private Function CreateProxy() As IDataService
Dim proxy As new DataServiceProxy
AddMyBehavior(proxy)
Return proxy
End Function
Private Sub AddMyBehavior(ByVal proxy As DataServiceRemoteProxy)
'Somecondition If Then
Dim behavior = New MyBehavior()
proxy.Endpoint.Behaviors.Add(behavior)
' End If
End Sub




Here the DataServiceProxy is the derived class of ClientBase with the generic type as IDataService ie declaration as


Public Class DataServiceRemoteProxy
Inherits System.ServiceModel.ClientBase(Of IDataService)
Implements IDataService
End Class





This is very simple.But if we have more services such as EmployeeService,CustomerService etc…and we need to add the same behavior we need to think about a more generic way of AddMyBehavior.That means we need to accept common base class of DataServiceProxy and EmployeeServiceProxy which is nothing but ClientBase<T> where T may be IDataService or IEmployeeService.If we just use generic variable as T it cannot recognize the EndPoint property which is specific to the ClientBase.Since we don’t have a non generic base class of ClientBase most people uses object as parameter and writes non type safe code or dynamic keyword.

So the question here is how to make the AddMyBehavior to accept any proxy and add the behavior.In the first look it may be complicated and there will be a tendency to pass as object or use the dynamic keyword.But there is a typed way.See the below code snippet.




Friend Shared Sub AddMyBehavior(Of T As Class)(ByVal proxy As ClientBase(Of T))
'Some condition If () Then
Dim cookieBehavior = New MyCookieBehavior()
proxy.Endpoint.Behaviors.Add(cookieBehavior)
'End If
End Sub




Here the ClientBase class accepts only the reference types.That’s why the Class keyword came into play.




Happy Coding!!!

No comments: