Pages

Wednesday 8 August 2012

WHY MY ANONYMOUS TYPE CANNOT BE IDENTIFIED AS SAME TYPE IN ANOTHER ASSEMBLY?



WHY MY ANONYMOUS TYPE CANNOT BE IDENTIFIED AS SAME TYPE IN ANOTHER ASSEMBLY?

When we return an anonymous type from different assembly, assembly creates a different identification for the specific type
For e.g. CalledClass [In CalledAssembly which has customerDetail type will have different identification from the customerDetail type in the calling class].

Using reflection we can access anonymous type from another assembly but not suggestible which make your assemblies tightly coupled and maintainability will be too complex.
Reference for access anonymous from different assemblies:
http://blogsprajeesh.blogspot.com/2008/05/accessing-anonymous-types-from.html

Workarounds to access types across assemblies:

1. Using dynamic objects

Caveats:

Option strict should be OFF in VB.NET

2. Using Tuples
References:
http://msdn.microsoft.com/en-us/library/bb384767.aspx

Wednesday 4 April 2012

Return multiple variables from VB.NET function


Problem:

How to return multiple variables from a single method call?

Scenario:

To fetch error messages with the warning level based on the error code, there could be more scenarios in similar fashion. Almost every developer will be muddled for a moment how [?] and start thinking to overcome the situation in a better way.

Problem Code
Public Function GetErrorMessage(errorCode As IntegerAs ??
     Dim errorMessage As String = "How to return multiple values!"
     Dim errorWarningLevel As Integer = 3

     Return errorMessage
     Return errorWarningLevel
End Function


Queries while implementing the above code,

  •        What could be the return type [String/Integer/ etc…]?
  •        If we write multiple return code lines, will it return to the calling method what we expect?


There have been lots of workarounds to handle this scenario here are few,

  •        Split the method into two business operations/methods
  •        Create a type which holds the required properties and return the type
  •        Adding in a list/hash-table and read the variables looping or with specific key
  •        Return as object [base type] and type cast in the calling method


Couple of advanced coding workarounds,

  •        Create an anonymous type in the called method and return as object, caller will type cast and convert into specific type
  •        Create an [Iterator] function and [Yield] the return variables/types, we can implement this using C# and also added as new feature in VB11

  Workaround:

Here is simple data structure introduced in .NET framework 4.0 TUPLE
Tuple can hold up to 8 different types in a single instance and return back to calling method, it not only holds the values but also acts as factory class that create instance of its static members.

Workaround Code
Private Sub MyTuple_Load(sender As System.Object, e As System.EventArgsHandles MyBase.Load
        Dim errorDetails = GetErrorMessage(555)
        Dim errorMessage = errorDetails.Item2 'Item2 holds Error message in Tuple
        Dim errorWarningLevel = errorDetails.Item3 'Item2 holds Error WarningLevel in Tuple
    End Sub
 
Public Function GetErrorMessage(errorCode As IntegerAs Tuple(Of IntegerStringInteger)
        Dim errorMessage As String = "How to return multiple variables in a single method call!"
        Dim errorWarningLevel As Integer = 3
 
        'Commented old code for reference
        'Return errorMessage
        'Return errorWarningLevel
 
        'Option 1: using TUPLE helper method 
        Dim errorDetails = Tuple.Create(errorCode, errorMessage, errorWarningLevel)
 
        'Option 2: Using TUPLE constructor
        Dim errorDetails As New Tuple(Of IntegerStringInteger)(errorCode, errorMessage, errorWarningLevel)
 
        Return errorDetails
 
    End Function


Advantages of using Tuples:

  •        Strongly typed
  •        Can hold any defined type [Structured  data types]
  •        Implements IStructuralComparable and IStructuralEquatable

Monday 26 March 2012

Anonymous Types implementation in VB.NET

Anonymous types were designed to provide greater flexibility to create your own type at run time with a simple keyword {New} with as many properties you need, there is no limit in declaring properties with different types to create an anonymous type.

How to create an anonymous type?

Create an object and declare properties that you require, similar to the below mentioned code. After that .NET compiler will take care of everything.

New With {.FirstName = Robert, _
.MiddleName = De, _
                    .LastName = niro, _
                    .Age =27
                     }

What .NET compiler does?

It generates a sealed class similar to the anonymous type declared and it makes the type as immutable and properties declared will be read-only.

Advantages of using Anonymous type:


  • Compiler creates the code on fly and I believe compiler creates a better code than any developer.
  • Reduce in number of code files that holds properties and need not bother about maintenance.

Caveats in using anonymous type:


  • Scope of an anonymous type will be specific to the implemented member
  • Anonymous type neither can be used as parameters nor used as return types
  • Cannot be generated in designer files [HLD/DSD] as separate entity

HOW TO RETURN AN ANONYMOUS TYPE?

It’s really great that we can return an anonymous type and direct cast the object with the original type, then you can access the properties in the instead of using reflection. Kudos to Type inference in VB.NET which makes developer life easier with one setting {Option Infer On}, this helps you to get the actual type from calling methods without the mentioning the actual type name.

Below is the sample that return an anonymous type as object and in the caller class how we type cast using type inference,

Declare a member the returns an object as mentioned below, in the calling class

Public Function GetCustomerDetails() As Object
Return New With {.FirstName = Robert, _
                        .MiddleName = Sr, _
                    .LastName = Deniro, _
                    .Age =27
                     }
End Function
In the caller class
Dim customerDetail = CastCustomerDetail(GetCustomerDetails(), _
                                               New With {                       .FirstName = String.Empty, _
                                                                                                .MiddleName = String.Empty, _
                                                                                                               .LastName = String.Empty, _
                                                                                      .Age = 0
                                                    })

Private Function CastCustomerDetail (Of T)(customerDetail As Object, customerDetailType As T) As T
        Return DirectCast(customerDetail, T)
End Function
Now in the customerDetail variable you can access the properties of {.FirstName as Robert and .LastName as Deniro}

Caveats:

Anonymous types cannot be identified across assemblies with same type and can be realized at runtime and not in compile time {we will discuss this in the below section}