vb.net Getting a reference to a class by its name - vb.net

I'm trying to use reflection to get the instance of a class in vb.net. I have a class 'A' in my web project and to test it, i create a new aspx page and try to write the following:
Dim t as Type = Type.GetType("A")
This returns "Nothing". But if i do this:
Dim inst as A = new A()
Dim t as Type = inst.GetType()
t's type is "A"
So how come i can't get the type with GetType even if the name is exactly the same? It does works for things like System.Math though so i'm probably missing something as a newbie.

Two things:
You need to include the namespace of the type
If the type isn't in mscorlib or the currently executing assembly, you need to specify the assembly name as well (including version numbers and public key information if it's a strongly-named assembly).
So for instance, to get hold of System.Linq.Enumerable you'd need something like:
Type.GetType("System.Linq.Enumerable, System.Core, Version=4.0.0.0, " & _
"Culture=neutral, PublicKeyToken=b77a5c561934e089")

Related

Is it possible to reference the Name property of a solution through code?

Is it possible to reference the name of your solution in code?
I want to pull it to be used as a string similar to how you would use System.Reflection.MethodBase.GetCurrentMethod().Name to pull the name of the current method.
I browsed through the System.Reflection class but have not come across anything useful yet.
Dim solutionName As String = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName)
Above will give you you dll name which usually is the same as project name.
Make sure below Assembly Name matches your solution name and you will be gold.

Type.GetType fails even though class exists

I have a text file that contains different types of data on each row. I'm trying to read the file and create a different (sub)class instance for each one. So I did...
Dim t As Type = Type.GetType("DtaRow")
And this returns Nothing. This is odd, because the very next bit of code in the same file/namespace/everything is...
Public Class DtaRow...
In fact, the code I'm typing formerly just called it's New method without problem. So maybe I need to do this...
System.Reflection.Assembly.GetExecutingAssembly().GetType("DtaRow")
Nope, that's Nothing as well. So then I followed some instructions I found here about looping over the Assemblies to look in all of them... no luck there either. So then I try looking for "Int32" and a bunch of others, phail.
Can someone tell me the obvious thing I'm doing wrong here?
Since a single Assembly can have multiple Namespaces and a type of the same name can exist in more that one NameSpace, you have to qualify the type name with the Namespace. From MSDN:
If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.
' should work
myT = Type.GetType("MyNameSpace.DtaRow")
' similarly:
myT = Type.GetType("System.Int32")
The NameSpace is integral to the Type name and NET does much the same:
Dim a As New Animal
myT = a.GetType()
Console.WriteLine(myT.ToString())
' => MyApplication1.Animal
If the code is in a form or class in the same namespace, Me.GetType.Namespace will get you the string name you can prepend; or you can use a dummy class. However, the mention of using the code in/as an extension might make that problematic. First Me will not be legal and using a dummy type will report the NameSpace for the dummy object.
If there is only one NameSpace to deal with, just use a variable and set it once:
Friend myNameSpace As String
...
' elsewhere something like a MainForm sets it:
myNameSpace - Me.GetType().NameSpace & "."
Then, just prepend that to the type names you load.
For more than one involved NameSpace, I'd use a Dictionary(Of String, String) using the type name as the key and NameSpace qualified string as the value:
myTypeName.Add("DtaRow", "FooNameSpace.DtaRow")
myTypeName.Add("Animal", "CircusActs.Animal")

Value of type 'DOOD.ServiceReference1.Search' cannot be converted to 'DOOD.Search'

After adding service reference in web application it created reference.vb class with namespace
service reference1 and when i tried to assign
i created a class same as what web service is returning and assigning the object
Dim obj1 As Search
Dim obj1 = client.Search(date, name)
here i am getting Value of type 'DOOD.ServiceReference1.Search' cannot be converted to 'DOOD.Search'
how to resolve this ...
Once worked at a place where we had an app where you had to go into the Reference.vb file and remove the declaration of the classes (in your case, specifically class Search) entirely from the file -- every time you regenerated the service reference. (generally when you changed the interface to any of the functions).
The service would then return just your DOOD.Search and no typecasting issues.
The alternative is that you have to write an adapter to convert between the two.

How to get qualifiers for a class

I have the following code to create an instance of one of my classes based on the class name.
'Get a System.Type corresponding to the name of the parent class
Dim tt As Type = Type.GetType(item.ParentClass)
'Create an instance of the specified type using the types default constructor
Dim theObject As Object = Activator.CreateInstance(tt)
This works fine if I have the full class as in MainClassName.Namespace.ClassName
But if I try to do this with just ClassName, tt equals to nothing.
Is there a way to use ClassName and get the fully qualified name as in MainClassName.Namespace.ClassName
Is there a way to use ClassName and get the fully qualified name as in MainClassName.Namespace.ClassName
No. This cannot logically work. Consider the following case: you have two classes, Foo.X and Bar.X. Just specifying X is therefore ambiguous. Indeed that’s the motivation behind namespaces and fully qualified names in the first place.
Even if it were possible (for instance by returning a list of candidate types) this would be impractical since it would require the runtime to walk through the whole list of classes that are loaded by all referenced assemblies. This can be a huge number, even with just the basic framework loaded. GetType would be prohibitively inefficient.
You need to use Type.AssemblyQualifiedName, like this:
'part 1 of your code - store class name in a universal format
Dim className As String = GetType(item.ParentClass).AssemblyQualifiedName
'part 2 of your code - use a previously stored class name to create instance
Dim tt As Type = Type.GetType(className)
Dim theObject As Object = Activator.CreateInstance(tt)
Credit goes to this answer on SO.

Where is the Type class?

i just started learning vb.net.
But i couldnt find out where the System.Type class is.
I googled, but couldnt find any answers.
Here is what i did:
Module m
Sub Main(ByVal e as String())
Dim ass as Assembly = Assembly.LoadFrom(e(0))
Dim assobj as Type() = ass.GetTypes()
For Each m As Type In assobj
Console.WriteLine(m.Name)
next
I changed the directory to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727> and supplied System.dll as argument
But i couldnt find Type class
So,where is the Type class??
If anything is wrong,ignore my ignorance.
Thank you.
Hello again,
i got another problem,this whole thing i mentioned above is about making a console app similar to java's javap.exe utility
if you give the class fullname as argument then it should print substantial info about the class.
the problem is - how do i know which .dll file to load depending upon the class name i give as input???(this is the reason why i expected System.Type would be in System.dll file)
I used ILSpy (free tool) to have a look. It is in the mscorlib.dll
Like Michal and Mr Lister stated it's in mscorlib.dll.
I found it a different way though, if take your code
Dim assobj as Type() = ass.GetTypes()
and right click on the word Type and press "Go To Definition" (shortcut key F12)
The default display is slightly different for VB.net & C#. (For me anyway)
For VB.Net:
You'll see the Object Browser, you can notice that the Type is a Member of System
If you click on System you'll notice that it is a member of mscorlib. If you click on mscorlib, then you can see where the DLL is actually stored.
If you are using C# then you will see:
#region Assembly mscorlib.dll, v4.0.30319
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\mscorlib.dll
#endregion
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Security;
namespace System
{
// Summary:
// Represents type declarations: class types, interface types, array types,
// value types, enumeration types, type parameters, generic type definitions,
// and open or closed constructed generic types.
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_Type))]
[ComVisible(true)]
public abstract class Type : MemberInfo, _Type, IReflect
{
//snip
}
}