Is there a way to convert a string representation of a type name into a Type object?

D

Deckarep

I want to be able to pass in a function a string say: "TextBox"

Then I need a way to convert that string representation into a Type
object so i can search through some controls and check their type.

Then I can do my check: If ( control is type) { //continue }

I'm doing this inside of a recursive function which goes through the
ControlTree.

Thanks in advance,

-Ralph

P.S. I would pass in a Type object to begin with into my recursive
call like typeof(TextBox) but my recursive function breaks and claims
that it doesn't have access to protected type member. I have no idea
why this happens.
 
M

Mark Rae

P.S. I would pass in a Type object to begin with into my recursive
call like typeof(TextBox) but my recursive function breaks and claims
that it doesn't have access to protected type member. I have no idea
why this happens.

Please show us the code which you are using, and the error message(s)
produced...
 
M

Marc Gravell

The string approach is probably going to be ugly compared with a Type
approach; can you describe what went wrong / what you tried?
Personally I'd rather try and fix this the right way. Getting a Type
from a string is possible, but is easiest if you have the fully-
qualified name. Without it, a more pragmatic approach might be to test
whether eachControl.GetType().Name == theNameYouKnow.

I don't have it to hand, but on a machine that is shut down for the
weekend (miles away) I have a utility function something like (notepad
code):

static void ActionAll<T>(Control control, Action<T> action) where T :
Control {
if(control == null) throw new ArgumentNullException("control");
if(action == null) throw new ArgumentNullException("action");
T t = control as T;
if(t!=null) action(t);
foreach(Control child in control.Controls) {
ActionAll<T>(child, action);
}
}

[I might have optimised it with a queue/stack to avoid recursion, and
avoid repeatedly testing for null]

This allows me to say (as an example):

ActionAll<TextBox>(this, delegate(TextBox tb) {
tb.SomePropertySpecificToTextBox = "blah";
tb.SomeTextBoxSpecificMethod("bloop");
});

You get the idea...

Marc
 
D

Deckarep

The string approach is probably going to be ugly compared with a Type
approach; can you describe what went wrong / what you tried?
Personally I'd rather try and fix this the right way. Getting a Type
from a string is possible, but is easiest if you have the fully-
qualified name. Without it, a more pragmatic approach might be to test
whether eachControl.GetType().Name == theNameYouKnow.

I don't have it to hand, but on a machine that is shut down for the
weekend (miles away) I have a utility function something like (notepad
code):

static void ActionAll<T>(Control control, Action<T> action) where T :
Control {
if(control == null) throw new ArgumentNullException("control");
if(action == null) throw new ArgumentNullException("action");
T t = control as T;
if(t!=null) action(t);
foreach(Control child in control.Controls) {
ActionAll<T>(child, action);
}

}

[I might have optimised it with a queue/stack to avoid recursion, and
avoid repeatedly testing for null]

This allows me to say (as an example):

ActionAll<TextBox>(this, delegate(TextBox tb) {
tb.SomePropertySpecificToTextBox = "blah";
tb.SomeTextBoxSpecificMethod("bloop");

});

You get the idea...

Marc


private void RecurseFindControlTree( ControlCollection cc, Type
typeToFind, List<Control> foundList )
{
foreach(Control c in cc)
{

if( c is typeToFind)
foundList.Add(c);

RecurseFindControlTree(c.Controls, t, foundList);
}
}


I'm trying to do this which is not working...the compilar says "Can't
access protected member typeToFind" but type is a local member to
this recursive function. I'm not even doing anything sophisticated
just some dirty recursion to get some reporting done for my controls.
I know there's a bunch of better ways to do this but I just want to
get the code working of what I showed above.
 
A

Alberto Poblacion

Deckarep said:
private void RecurseFindControlTree( ControlCollection cc, Type
typeToFind, List<Control> foundList )
{
foreach(Control c in cc)
{

if( c is typeToFind)
foundList.Add(c);

RecurseFindControlTree(c.Controls, t, foundList);
}
}


[...] the compilar says "Can't
access protected member typeToFind" but type is a local member to
this recursive function.

"is" does not allow you to use a variable in this way; it expects a type
that is known to the compiler. You can make it work if you pass the Type as
a Generic parameter like this:


private void RecurseFindControlTree<typeToFind>(ControlCollection cc,
List<Control> foundList)
{
foreach (Control c in cc)
{

if (c is typeToFind)
foundList.Add(c);

RecurseFindControlTree<typeToFind>(c.Controls, foundList);
}
}
 
J

Jon Skeet [C# MVP]

Deckarep said:
I want to be able to pass in a function a string say: "TextBox"

Then I need a way to convert that string representation into a Type
object so i can search through some controls and check their type.

If you pass in the fully-qualified name of the type (including
namespace), you can use Type.GetType. However, be warned that it will
only search mscorlib and the currently executing assembly unless you
*also* provide the assembly details. Look at Type.GetType for more
information. If the types you're interested in are always from the same
assembly, you could use Assembly.GetType.
Then I can do my check: If ( control is type) { //continue }

No, you can't do it like that - you need to use Type.IsAssignableTo (or
a similar method). The right hand operand of "is" is the name of a type
at compile time.
P.S. I would pass in a Type object to begin with into my recursive
call like typeof(TextBox) but my recursive function breaks and claims
that it doesn't have access to protected type member. I have no idea
why this happens.

I'd try to fix that rather than using Type.GetType.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
D

Deckarep

Hi Jon,

I don't think there's a need to post my application.

I can clearly see that trying to check for my type via the 'is' syntax
is what was wrong.

I thought I can just a check for 'is' against a Type object...but that
simply won't do.

Anyways, thanks for all the help to everyone...now I have a couple of
solutions to work from. But I think the best solution is just
changing my code to use generics which has worked like a charm.

And by the way Jon I didn't know I could use Assembly.GetType( string
s ). This will definately help with some situations where I'm still
working with 1.1 code.

Thanks again,

-Ralph
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top