Exception with System.Type.GetType(...) function
Hello all,
I have a strange problem with the System.Type.GetType(...) function.
When I do :
try
{
string maChaine = "System.Windows.Forms.Button";
Type ty = Type.GetType(maChaine, true);
}
catch (Exception ex)
{
label1.Text = ex.Message;
}An exception raises ; the message is (I translate ...)
"Impossible to load the typeSystem.Windows.Forms.Button from the assemblyWindowsApplicationXXX, Version xxx, ...Why this exception ? Have you an idea ?
[536 byte] By [
Syl20] at [2008-2-5]
Syl20 wrote: |
| Hello all, I have a strange problem with the System.Type.GetType(...) function. When I do : try { string maChaine = "System.Windows.Forms.Button"; Type ty = Type.GetType(maChaine, true); } catch (Exception ex) { label1.Text = ex.Message; } An exception raises ; the message is (I translate ...) "Impossible to load the type System.Windows.Forms.Button from the assembly WindowsApplicationXXX, Version xxx, ...Why this exception ? Have you an idea ? |
|
Syl20,
The reason for this is that you are using the short name for the type when calling GetType. If the type is not in MSCORLIB.dll, and it is not in the current assembly that you are making the call to GetType from, then you need to use the full type name (with assembly information) in order to get the type. Otherwise, the runtime doesn't know how to resolve the assembly to get the type.
Hope this helps.
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
Thanks for your reply, CasperOne.
You mean "System.Windows.Forms.Button" is a short name ?
I have added references to "System.Windows.Forms" but nothing change ...
So how can I simply get a System.Type from the string "System.Windows.Forms.Button" ?
Thanks a lot
Syl20 wrote: |
| Thanks for your reply, CasperOne. You mean "System.Windows.Forms.Button" is a short name ? I have added references to "System.Windows.Forms" but nothing change ... So how can I simply get a System.Type from the string "System.Windows.Forms.Button" ? Thanks a lot |
|
Syl20,
Just because you have a reference to that assembly doesn't mean that the same type can't be defined elsewhere (and even in the same namespace, which is actually allowed if you load two assemblies with different versions at the same time).
The full name of the type is:
System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
This is for the Button class in the System.Windows.Forms namespace in .NET 2.0 beta 1. If you are using another version, the version and public key token (I believe) will be different.
Also, if you want the fully qualified name, you can get the type for the object through GetType, and then call the AssemblyQualifiedName property to get the full name.
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
Thanks CasperOne.
But :
* I can't know the fully qualified name of the component, because the application will be deployed on many computers.
* I can't use the GetType function on components, the string corresponding to the componend comes from a XML file.
In fact my problem is (sum up) :
How could I have a System.Type from a String which represents only a short name of an object type ?
Thanks
Syl20 wrote: |
| Thanks CasperOne. But : * I can't know the fully qualified name of the component, because the application will be deployed on many computers.
|
|
This has nothing to do with the component name. The assembly qualified name of the type has nothing to do with the machine that it is installed on.
Syl20 wrote: |
* I can't use the GetType function on components, the string corresponding to the componend comes from a XML file.
|
|
This isn't a problem. You can easily find out the full name of the component by doing:
| |
Console.WriteLine(typeof(System.Windows.Forms.Button).AssemblyQualifiedName);
|
You can then then paste that output into your XML file.
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
I do not understand. You say :
This is for the Button class in the System.Windows.Forms namespace in .NET 2.0 beta 1. If you are using another version, the version and public key token (I believe) will be different.
then
The assembly qualified name of the type has nothing to do with the machine that it is installed on.
I think the assembly qualified name is based on the version of the framework you use.
I cannot modify the XML file ; it is the input of my application ...
What is strange is that I have 2 applications ; they have the same using and references. One goes on well with
| | try { string maChaine = "System.Windows.Forms.Button"; Type ty = Type.GetType(maChaine, true); } catch (Exception ex) { label1.Text = ex.Message; } |
and not the other (the exception is throwed).
Why ?
Can you do something like this? You're going to have to find some way to get the AssemblyQualifiedName. This is one way I thought of.
try
{
string maChaine = "System.Windows.Forms.Button," +label1.GetType().Assembly.FullName;
Type ty = Type.GetType(maChaine, true);
label1.Text = ty.AssemblyQualifiedName;
}
catch (Exception ex)
{
label1.Text = ex.Message;
} Syl20 wrote: |
| I do not understand. You say : This is for the Button class in the System.Windows.Forms namespace in .NET 2.0 beta 1. If you are using another version, the version and public key token (I believe) will be different. then The assembly qualified name of the type has nothing to do with the machine that it is installed on. I think the assembly qualified name is based on the version of the framework you use. I cannot modify the XML file ; it is the input of my application ... What is strange is that I have 2 applications ; they have the same using and references. One goes on well with | | try { string maChaine = "System.Windows.Forms.Button"; Type ty = Type.GetType(maChaine, true); } catch (Exception ex) { label1.Text = ex.Message; } | and not the other (the exception is throwed). Why ? |
|
Syl20,
You are right, the assembly qualified name is dependent on the version you use, for this particular type, because the version of the assemblies in any version of .NET is tied to the version of .NET.
You are going to have to change the input of your file to show the correct name. The reason for this is that if you don't have the assembly qualified name of the type, you don't know which assembly you will have to look in in order to get the type information you need.
As for your exception being thrown, the code you listed has an empty exception handler for all exceptions, so the exception is being thrown, it is just being swallowed.
The assembly qualified name is the only way to truly handle the type name in this situation.
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
Chris J. Breisch wrote: |
Can you do something like this? You're going to have to find some way to get the AssemblyQualifiedName. This is one way I thought of.
try { string maChaine = "System.Windows.Forms.Button," +label1.GetType().Assembly.FullName; Type ty = Type.GetType(maChaine, true); label1.Text = ty.AssemblyQualifiedName; } catch (Exception ex) { label1.Text = ex.Message; }
|
|
Chris,
You could do this, but generally speaking, it's a guess, because you don't know that a label won't be moved to another assembly (although in this case, it most likely never will, as a general purpose algorithm, it will break easily if types move between assemblies).
Also, generating your own fully qualified type names is a bad idea. It's best to let the framework handle them.
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
casperOne wrote: |
This is for the Button class in the System.Windows.Forms namespace in .NET 2.0 beta 1. If you are using another version, the version and public key token (I believe) will be different.
|
|
The public key token will be the same across framework versions, but the version number may change. However, that v2.0.0.0 should be the same for v2.0 beta 2 and RTM.
-Shawn
One way might be:
| |
Assembly winForms = Assembly.Load("System.Windows.Forms); Type button = winForms.GetType("System.Windows.Forms.Button");
|
-Shawn