2

I have some code like:

Lookup(Of String)("Testing")
Lookup(Of Integer)("Testing")

And both of those Lookups work great. What I'm trying to is call the appropriate LookUp based on the type of another variable. Something that would look like...

Lookup(Of GetType(MyStringVariable))("Testing")

I've tried to Google this but I'm having a hard time coming up with an appropriate search. Can anyone tell me how to do what I want?

Larsenal
  • 49,878
  • 43
  • 152
  • 220
Rob P.
  • 14,921
  • 14
  • 73
  • 109
  • Please give an example of how you are using those `Lookup`s – John Saunders Sep 17 '09 at 20:11
  • Type of _variable_, or type of _value_ currently held by this variable? I.e. in case of `Dim x As Object = 123`, do you want `Object` or `Integer`? – Pavel Minaev Sep 17 '09 at 20:22
  • It's actually used to open Forms of different types in the application. The 'current' form is a particular type and I want to call this Lookup with the type of the current form. There is an ugly case statement that says, 'If the current form is X then Lookup (Of X)("Some Stuff"), if the current form is Y then Lookup (Of Y)'. I just want to say 'Lookup(Of Whatever Type the Current Form Is)' but I don't know how. – Rob P. Sep 17 '09 at 20:23
  • "in case of Dim x As Object = 123, do you want Object or Integer?" - I'd want 'Object'. Although, in my particular case, I'd have 'Dim x as Integer = 123' so I think I'd get the same result in either case, but I'm just speculating. – Rob P. Sep 17 '09 at 20:26

4 Answers4

5

You do not specify the full signature for the method that you're calling, but my psychic powers tell me that it is this:

Function Lookup(Of T)(key As String) As T

And you want to avoid having to repeat Integer twice as in the example below:

Dim x As Integer
x = Lookup(Of Integer)("foo");

The problem is that type parameters are only deduced when they're used in argument context, but never in return value context. So, you need a helper function with a ByRef argument to do the trick:

Sub Lookup(Of T)(key As String, ByRef result As T)
    T = Lookup(Of T)(key)
End Sub

With that, you can write:

Dim x As Integer
Lookup("foo", x);
Pavel Minaev
  • 99,783
  • 25
  • 219
  • 289
  • I'm not a fan of ByRef arguments if they can be helped (though they may be needed at times). But +1 for the clever approach. :) – eidylon Sep 17 '09 at 20:48
  • That is very cool. And very much what I was looking for. As a follow up; what would I search for/read if I really wanted to understand what is going on here? This would be 'Generics' and not 'Reflection', correct? – Rob P. Sep 17 '09 at 20:50
  • Yes, you want generics, generic methods to be precise. Reflection would only have to be involved if you'd want it to depend on types that are only known at run time and not at compile time (such as the type of actual value a variable has). Specifically, see http://msdn.microsoft.com/en-us/library/w256ka79.aspx and http://msdn.microsoft.com/en-us/library/ms235246.aspx – Pavel Minaev Sep 17 '09 at 20:56
1

One solution to this is to use reflection. See this question for details.

Community
  • 1
  • 1
scott
  • 748
  • 6
  • 10
1

The VB.NET compiler in VS2008 actually uses type-inference. That means if you are using a generic method, and one of the parameters is of the generic type, then you don't need to specify the generic type in your call.

Take the following definition...

Function DoSomething(Of T)(Target As T) As Boolean 

If you call it with a strongly-typed String for Target, and don't specify the generic parameter, it will infer T as String.
If you call it with a strongly-typed Integer for Target, and don't specify the generic parameter, it will infer T as Integer.

So you could call this function as follows:

Dim myResult As Boolean = DoSomething("my new string")

And it will automatically infer the type of T as String.

EDIT:
NOTE: This works for single or multiple generic parameters.
NOTE: This works also for variables in the argument list, not just literals.

eidylon
  • 7,068
  • 20
  • 75
  • 118
  • Lookup(Of GetType(MyVariable)) gives me an error of 'Keyword does not name a type.' I'll take a closer look and see if I can find what I've done wrong. – Rob P. Sep 17 '09 at 20:29
  • Yes, GetType must be used on an actual type name, like , , etc. But the point here is you do not need to specify the type. Just pass your variable into the function, and leave out the generic parameter in your function call. I'm working under the assumption your function is defined as Function Lookup(Of T)(argument As T). – eidylon Sep 17 '09 at 20:35
  • I suspect that in his case `T` is not argument type, but is rather result type. – Pavel Minaev Sep 17 '09 at 20:38
  • Rob, can you update your OP and include the definition of the Lookup function, so we can get a better understanding? – eidylon Sep 17 '09 at 20:42
1

You can't use a dynamic type unless you do runtime compiling, which of course is really inefficient.

Although generics allows you to use different types, the type still has to be known at compile time so that the compiler can generate the specific code for that type.

This is not the way to go. You should ask about what problem you are trying to solve, instead of asking about the way that you think that it should be solved. Even if it might be possible to do something close to what you are asking, it's most likely that the best solution is something completely different.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005