Type.GetType(string) question

  • Thread starter Thread starter Martin Eckart
  • Start date Start date
M

Martin Eckart

Hi folks,

Who can explain me why the following expression does not result in getting
the correct type, but null:

Type t = Type.GetType("System.Xml.XmlReader");

For "System.String" it works as well as for "System.IO.Stream" or
"System.Globalization.CultureInfo". Does that related to the constructor of
XmlReader being not public?

Thanks,
Martin
 
Type.GetType() doesn't automatically search all assemblies for the type;
actually, it expects an "assembly qualified name", but will forgive
you (i.e. allow the short name) if the type is found in either the
calling assembly (your code) or mscorlib.dll (common types).

The following is the aqn version of XmlReader (watch for wrap):

Type t = Type.GetType("System.Xml.XmlReader, System.Xml,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");

The easiest way to get the aqn is via:
string aqn = typeof(XmlReader).AssemblyQualifiedName;

(then write that to the trace or something if you want it for a config
file etc)

Marc
 
Hi Marc,

That already helps.

Now, the issue I have is that I get a string value set to
"System.Xml.XmlReader". But it could also be "System.String" or
"System.Xml.XmlNodeList" or whatever. Therefore I cannot issue the code line
string aqn = typeof(XmlReader).AssemblyQualifiedName;
statically, but have to replace the "typeof(XmlReader)" by something like
"typeof(<myInputString>)".

Is there a way to accomplish that?

Thanks,
Martin
 
Yes, have. Has nothing do to with it.


Who can explain me why the following expression does not result in
getting
the correct type, but null:

Type t = Type.GetType("System.Xml.XmlReader");

Do you have the System.Xml assembly referenced in your assembly?

Pete
 
That already helps.

Now, the issue I have is that I get a string value set to
"System.Xml.XmlReader". But it could also be "System.String" or
"System.Xml.XmlNodeList" or whatever. Therefore I cannot issue the code line
string aqn = typeof(XmlReader).AssemblyQualifiedName;
statically, but have to replace the "typeof(XmlReader)" by something like
"typeof(<myInputString>)".

Is there a way to accomplish that?

No - typeof(...) is a compile-time operator - it looks up the type
name based on the context of the code and the referenced assemblies,
and works out the fully-qualified name at compile-time.

What you *can* do is recursively look through the assemblies
referenced by your current assembly (I can't remember the method name
off hand, but it's something obvious like
Assembly.GetReferencedAssemblies) and call Assembly.GetType on each of
those assemblies until you find the type.

Jon
 
The "typeof" line was just so you could obtain the assembly-qualified
name of the type - this isn't something you'd normally keep in the real
code. The idea being to use the assembly-qualified name *instead* of
"System.Xml.XmlReader". Of course, if this isn't an option you'll have
to start trawling assemlbies...

Marc
 
What you *can* do is recursively look through the assemblies
referenced by your current assembly

Actually, one thing to note here is that the compiler is clever - it
will drop things that you have referenced but not used... just one to
watch if it doesn't work. You also need to watch for the circular
reference at the bottom ;-p

But something like below.

Marc

using System;
using System.Collections.Generic;
using System.Reflection;
static class Program
{
static void Main()
{
Type type = GetType("System.Xml.XmlReader");
}
static Type GetType(string name)
{
// tryu the lazy way first
Type type = Type.GetType(name);
if (type != null) return type;

List<string> skip = new List<string>();
AssemblyName root = Assembly.GetEntryAssembly().GetName();
return WalkAssemblies(name, root, skip);
}
static Type WalkAssemblies(string name, AssemblyName an,
IList<string> skip)
{
// check "an" for the type
skip.Add(an.FullName);
Assembly a;
try {
a = Assembly.Load(an);
} catch {
return null; // oops
}
Type type = a.GetType(name);
if (type != null) return type;

// see what is referenced
foreach(AssemblyName nextRef in a.GetReferencedAssemblies()) {
if(skip.Contains(nextRef.FullName)) continue;
type = WalkAssemblies(name, nextRef, skip);
if (type != null) return type;
}
return null;

}
}
 
Marc Gravell said:
Type.GetType() doesn't automatically search all assemblies for the type;
actually, it expects an "assembly qualified name", but will forgive you
(i.e. allow the short name) if the type is found in either the calling
assembly (your code) or mscorlib.dll (common types).

The following is the aqn version of XmlReader (watch for wrap):

Type t = Type.GetType("System.Xml.XmlReader, System.Xml, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089");

If you use just typename and assembly-name (no "Version" etc), then GetType
will find it (*if* the assembly was referenced).
So: Type t = Type.GetType("System.Xml.XmlReader, System.Xml");

Hans Kesting
 
Back
Top