GetType and TypeOf confusion

Both VB and C# have an operator called TypeOf (or typeof in C#) but they perform two completely different things.

In VB there are also two kind of GetType() calls, the object.GetType() method which is part of the .Net framework and the VB language specific GetType() operator.

Are you confused yet? Don’t worry, in this article I will try to explain the difference between these operators and the object.GetType() method.

The TypeOf, typeof, GetType operators

The VB TypeOf operator is used together with the Is keyword and is used for checking if an object is of a particular type.

result = TypeOf x Is String


If “x” above is a string then “result” would be True otherwise it is set to False. This operator have existed in VB since long before .Net was born. The equivalent for the TypeOf operator in C# is simply called the is operator.



result = x is string;



The typeof operator in C# on the other hand returns an instance of the System.Type class containing type declarations of the type you pass to it.



Type t = typeof(string);


The VB equivalent of the C# typeof operator is the GetType operator.



Dim t As Type = GetType(String)


The reason for the different names are simply because of the fact that TypeOf was already a reserved keyword in VB and I guess the C# team didn’t have VB in their mind when they designed C#. :)



The difference between Object.GetType and the GetType operator



On a trivial level, the Object.GetType() method operates on an object instance while the GetType (and C#’s typeof) operator operates on a type.



Dim s As String
Dim t As Type = s.GetType()
Dim t2 As Type = GetType(String)



There are no differences between “t” and “t2” in the above code. So why do we have to have both of them? Well, you might not know what type a certain reference is made of in which case you obviously can’t use the GetType operator since that requires that you pass the type. Have a look at the following example:



Public Class MyBaseClass
End Class

Public Class MyDerivedClass
  Inherits MyBaseClass
End Class

Module Test
  Public Sub ShowType(ByVal obj As MyBaseClass)
    Dim t As Type = obj.GetType()
    Dim t2 As Type = GetType(MyBaseClass)
    Console.WriteLine(t)
    Console.WriteLine(t2)
  End Sub

  Public Sub Main()
    Dim myObject As New MyDerivedClass
    ShowType(myObject)
    Console.ReadLine()
  End Sub
End Module


In this example the ShowType method takes a MyBaseClass parameter and t2 uses the GetType operator to get the System.Type representation of MyBaseClass. So when you write out t2 to the console it will write MyBaseClass. However when you use the GetType method on the obj parameter it will write MyDerivedClass to the console. It is legal to pass a reference to MyDerivedClass to the ShowType method since it inherits from MyBaseClass so that will be a widening conversion. So inside the ShowType method we will never know if the parameter contains the type we have declared it as or if it contains any subclass of it, to find out we need to use the Object.GetType method.



Another difference between the method and the operator is when you’re dealing with value types.



Dim i As Integer
Dim t As Type = i.GetType()
Dim t2 As Type = GetType(Integer)



In order to call i.GetType() above i must first be converted to an Object which means a boxing conversion has to be done. Using the operator no boxing conversions are made which in this case makes that call faster.



I hope this removes some of the confusion about this subject, if not please feel free to leave a comment.



Have fun!

Boxing and Unboxing in .Net

In this article I will try to explain the concepts of Boxing and Unboxing. There are two types of objects within the .Net framework, value types and reference types. Value types are stored on the stack while reference types are always stored on the heap. Converting a value type into a reference type is called Boxing while converting it back from a reference type to a value type is called Unboxing.

Value Types

Value types are primitive types like System.Int32 (Integer in VB, int in C#) or System.Double. These types are mapped directly to the Framework Class Library (FCL) and are all derived from System.ValueType. Apart from the regular primitive types (integer, long, single, double, char, and so on) Enumerations and Structures also inherits from System.ValueTypes so they are also stored on the stack.

Reference Types

All classes are reference types and they are stored on the heap. So when you create a new instance of a class using the new keyword, memory are allocated on the heap for the object and the memory address is returned. Strings are a special case since they are also reference types, even though they are often treated as if they where value types, but that’s not the case. The difference is that you don’t have to create an instance of a string in the same manner as you would with another class.

Reference types are also Nullable, meaning that you can set the reference to Null (Nothing in VB).

Widening and Narrowing conversions

Before we go into the Boxing and Unboxing I would like to take a moment to explain the difference between a widening and a narrowing conversion. A widening conversion is always safe since there is never any risk of any data loss. For example converting an Integer into a Long (System.Int64) is a widening conversion. There is no integer value that doesn’t fit into a Long so you can always do that. However doing the opposite, converting a Long into an Integer is more risky since there are a chance that you will lose some data, since a Long can contain a number that is too high (or too low) to fit into an integer.

You can always use an implicit conversion when you do a widening conversion.

Dim i As Integer = 3
Dim l As Long
l = i 'Implicit conversion



However to do the opposite, a narrowing conversion, you need to do an explicit conversion.



i = CType(l, Integer) 'Explicit conversion
'or
i = CInt(l) 'Explicit conversion



If you don’t do an explicit conversion when you’re doing a narrowing conversion you will get a compilation error so your project will not compile (Note, VB can allow you to do an implicit conversion if you have Option Strict set to Off, something I strongly advice you not to have, C# however will never allow it). If the Long value does not fit into the Integer you will however still get a runtime error since the system will then throw a System.OverflowExeption. So when you do a narrowing conversion you must be sure that it can be done.



Doing Boxing/Unboxing



As mentioned earlier Boxing refers to the conversion of a value type to a reference type.



Dim i As Integer = 3
Dim o As Object
o = i 'Boxing the Integer into an object (reference type)



Above I do an implicit conversion of an integer to an object. This is possible since it’s a widening conversion so there is no risk of any data loss. However doing the opposite, converting the object to an integer is a narrowing conversion, where there is a risk that data will be lost.



i = o 'Implicitly doing a narrowing conversion (not allowed)
i = CInt(o) 'Explicitly doing a narrowing conversion (allowed)



In C# if you have boxed a particular type you must unbox it to the same type. You can not box an integer to an object and then unbox it to a long.



int i = 3;
long l;
object o;
o = i;
l = (long)o; //will throw a System.InvalidCastException


For the above to work, you must first unbox it to an integer and then cast it to a long.



int i = 3;
long l;
object o;
o = i;
l = (long)(int)o;



However the VB’s type conversion functions (CType and the more specific CInt, CLng, CDbl and so on) does allow this.



Dim i As Integer = 3
Dim l As Long
Dim o As Object
o = i
l = CLng(o) 'allowed



End words



I hope that you by now have a better understanding of Boxing and Unboxing. So let me end this article by saying that you should avoid doing this if possible. Doing type conversion is time consuming, and that is especially true when it comes to Boxing and Unboxing since data have to be transferred back and forth between the stack and the heap. Using Generics, which has existed in .Net since version 2.0, is a much better approach than having to deal with value type to reference type conversion.



I will cover Generics in a later article.



Have fun.

Top 10 signs that you are a geek

Here’s a compilation of my personal view of top 10 signs that you are a geek, in descending order.


9. You see a guy drink a pint of beer in less than 8 seconds and you are impressed by his download speed.


8. You don’t say that people are standing in a long line outside a popular night club but that they are caught in a slow serial queue. Not that you would ever find yourself in that situation since you don’t have a social life.


7. You wear a T-shirt that reads <body> on the front and </body> on the back and you don’t understand why people doesn’t find it funny.


6. You know that the answer to the riddle: “If only you and DEAD people knows HEX, how many people knows HEX?” is 57,006, and you also think that this is one of the funniest jokes you’ve ever heard. Likewise you also think that the statement “There are 10 kinds of people in the world, those that know binary and those that doesn’t” is hilariously funny.


5. You think that the correct term for a buoy is a floating point.


4. You tape down two of your child’s fingers just to teach him/her to count in octo.


3. One of your most treasured belongings is your 30 year old TI-34 calculator.


2. You don’t understand why (most (apart from yourself)) people think that using nested parenthesis when they type is bad practice.


1. You tweet hateful arguments and post several blog articles about how bad your current phone carrier is just because they wouldn’t give you a phone number containing 7331 in it.


0. All your “Top 10” lists are zero-based.


So there you have it. Have fun!

Nifty extension methods

One of my favorite features in .Net 3.5 is the ability to extend a class using extension methods. Earlier you could only extend a class either by creating a new class that inherits from the first class or you could create a partial class. Of course if you have the source code of the original class you could just write the new code directly in it and recompile it. In many cases you don’t have access to the source code of a class and if the class is also sealed (NotInheritable in VB) you would not be able to extend its behavior using the other methods either. The string class is a typical example of a class that is sealed and you normally wouldn’t be able to extend at all. That is until extension methods entered the scene.

In VB extension methods must reside inside a module and be decorated with the Extension attribute (available in the System.Runtime.CompilerServices namespace), in C# they need to be defined in a static class and use the this keyword on the first parameter (the method does not have to be decorated with the Extension attribute in C#).

Let say that you want to extend the string class with a method that allows you to do a case-insensitive comparison with another string. Many programmers use the ToUpper or ToLower methods on the strings before comparing them, but that doesn’t always give the correct result and you should avoid doing that. The reason is that these methods are not always culture aware. Take the ß (the sharp S or double S in German) character for example. It is considered to be a lower case character which in upper case should be written as two S’es. Straße (street) versus STRASSE, but calling ToUpper on the word Straße does not return STRASSE, so comparing the two spellings using the ToUpper or ToLower methods will fail. A much better approach would be to use the CaseInsensitiveComparer class (from the System.Collections namespace).

OK, so let’s look at the code for what that extension method could look like.

Imports System.Collections.Generic
Imports System.Runtime.CompilerServices

Public Module ExtensionMethods
<Extension()> _ Public Function EqualsText(ByVal str As String, ByVal equalsTo As String) As Boolean Dim sc As New CaseInsensitiveComparer Return (sc.Compare(str, equalsTo) = 0) End Function End Module


As you can see it simply looks as a small helper function that accepts two strings and returns a boolean. The thing is that when you use this as an extension method, the first parameter type tells the compiler what kind of object you are extending. So when you call it you would only pass in one parameter as you can see in the image below.



image




Enough introduction show some more nifty extension methods


One of the top features in VB9 is that you can work with XML literals, in my opinion one of the best features since IntelliSense was introduced back in VB5. Even if you don’t work much with XML (does people like that still exist?) you can still use them in your source code. Take this simple code for example:



Dim sql As String = <query>select CustomerName from customer where CustemerID=@CustomerID</query>.Value



Here I actually create an XElement object using an XML literal, and then convert it to a string by calling the Value method, which returns the inner value of the element. OK so what’s the benefit of doing that instead of simply putting the text inside quotes? Well, in the above example there are no benefits at all, but your query is probably much longer than what’s shown above.



Dim sql As String = <query>
                      update customer set
                        CustomerName=@CustomerName,
                        Street=@Street,
                        City=@City,
                        Zip=@ZipCode,
                        State=@State
                      where CustomerID=@CustomerID
                    </query>.Value



OK, the above is still a very straight forward query but the idea here is that it’s much easier to read the query when you have it on different lines which you can’t do in VB without doing a lot of string concatenations. The problem with the above is that all whitespaces are contained within the string and there are several spaces at the beginning of each line. So why not write an extension methods that trims off the spaces?



    <Extension()> _
    Public Function TrimmedValue(ByVal xml As XElement) As String
        Return String.Join(vbLf, (String.Join(vbLf, ( _
             From s In xml.Value.Split(New Char() {Convert.ToChar(10)}) _
             Select s.Replace(vbTab, " ").Trim()).ToArray)).Split( _
             New Char() {Convert.ToChar(10)}, StringSplitOptions.RemoveEmptyEntries))
    End Function


Now you can use the TrimmedValue extension method instead of the Value method. Please note that you need to import the System.Xml.Linq namespace to work with XML literals.



Generic types


Extension methods also works with generics. Say you want to paginate an IEnumerable(Of T). There are actually already extension methods available to do this, they are called Skip() and Take().



Dim page = someIEnumerableType.Skip(30).Take(15)



The above will skip the first 30 elements and return the next 15. But let us combine that into one single call.



    <Extension()> _
    Public Function Paginate(Of T)(ByVal list As IEnumerable(Of T), _
                                   ByVal skip As Integer, _
                                   ByVal take As Integer) As IEnumerable(Of T)
      Return list.Skip(skip).Take(take)
    End Function



It’s now easy to paginate anything that implements the IEnumerable(Of T), which means any array or collection.



    Dim names As String() = {"Anders", "Bart", "Ceasar", "David", _
                             "Eric", "Fabian", "Gunnar", "Harald", _
                             "Ingemar", "Joacim", "Karl", "Lennart", _
                             "Martin", "Nick", "Olaf", "Peter", "Quintus", _
                             "Rolf", "Stephen", "Thor", "Ulf", "Valdemar", _
                             "Wiktor", "Xerxes", "Yngve", "Zach"}
    Dim page = names.Paginate(10, 5) 'returns "Karl" through "Olaf"


If you have used LINQ you probably familiar with anonymous types. They are a great way of creating a new object without first having to type the source for it, since the compiler takes care of that for you. But one of the problems with anonymous types is that they are nameless which makes it hard to create a new one of the same type or to create a list of them if you only have a single instance. However using generics and a simple extension method you can turn any type into a list. Deborah Kurata recently posted this code on her blog that demonstrated how you would do that.



    <Extension()> _
    Public Function ToList(Of T)(ByVal type As T) As List(Of T)
      Return New List(Of T)
    End Function



Of course that would only create a list of a specific type, it would not add anything to the list. If you like you could extend the code by adding the value to the list.



    <Extension()> _
    Public Function ToList(Of T)(ByVal type As T) As List(Of T)
      Dim list = New List(Of T)
      list.Add(type)
      Return list
    End Function





So what if you want to test if a type is Nullable?



    <Extension()> _
    Public Function IsNullable(Of T)(ByVal obj As T) As Boolean
      If obj Is Nothing Then
        'if it is Nothing already, it must obviously be nullable
        Return True
      End If
      Dim type = GetType(T)
      If Not type.IsValueType Then
        'if it's not a value type it must be a reference type and reference types are always nullable
        Return True
      End If
      'Nullable.GetUnderlyingType returns Nothing if the type passed to it isn't Nullable
      Return (Nullable.GetUnderlyingType(type) IsNot Nothing)
    End Function


More ideas


As you probably have noticed most of the above examples are pretty short helper functions that are turned into extension methods. The advantage is that you can use the object oriented dot syntax and get IntelliSense to help you make sure you spelled your code correctly. Of course there is no rule that states that an extension method must be brief, but I find that they usually are.



So what more can you do? How about this:



  • Extend a StringBuilder with a ToString method that accepts a delimiter and returns a string that is a delimited list of each line in the StringBuilder.
  • If you often need to store user inputted data in a database, maybe you should extend the String class to have a ToSecureSqlString that for example escapes all single quotes (using two single quotes).
  • Create an extension to the Control class that can do a recursive search for a child control.


You will soon notice that you have quit a large toolkit of nifty extension methods ready to be used in any of your projects.



Have fun!


kick it on DotNetKicks.com