creating new instance though reflection

B

bowser

Hello,
I'm new to C# but so far I didn't find big problems, except for
Reflection. I coudn't find any good material in internet where to study
it. If anyone knows about some documents, blogs or stuff, please let me
know.

My problem is that I have to create a new instance of a class, given a
type and a name (object's id) as parameters. The constructor of such
type has no parameters.

Type t;
string id;
ConstructorInfo ci = t.GetConstructor(new Type[] { });
ci.Invoke(null); // this creates the instance but how to bind it to id?
// I know there's a class named Binder, but how do
I have to use it?

Obviously, trying:
t id = ci.Invoke(null);
is not correct for 2 reasons: t is used as a type, while it's a
variable; secondly id is a string, not an identifier.

I tried also Activator.CreateInstance(m_class): what's the different
between this and the previous way?

Finally I need to know if the id (that I have as string variable), is
already binding another object, so that I can change it to do my work.

Thank you in advance.

Alessandro
 
M

Marc Gravell

"binding" doesn't apply here... can you clarify what you mean with the
"id is a string not an identifier"? This might mean you need to find
the field first...

ci.Invoke() should return the instance, but unless you are using
generics, all you can do is treat it as an object, i.e. object id =
ci.Invoke(null);

However, if you are talking about a paramererless constructor, then in
2.0 generics is the answer:

public static void SomeMethod<T>() where T : new() {
// do some work
T t = new T();
// do something with T...
}

of course, in the above you can't do much with t by itself, unless you
a: are putting it into an existing collection of Ts, or b: you know
that T supports certain features:

public static void SomeMethod<T>(IList<T> list) where T : new(),
ISomeInterface {
T t = new T();
list.Add(t);
t.SomeMethod();
}

If I understand your intent ("id as a string"), then another trick
might be:

public static void RecreateField<T>(ref T field) where T : new() {
field = new T();
}

This then allows you to call things like
"RecreateField(someTypedField);" and it will just work... of course,
unless you are doing something else in that code block it would be
easier to just type "someTypedField = new FieldType();"... so can you
clarify?

Marc
 
G

Guest

If you want to assign a class level field named with the contents of the id
string then you will need to call something like this:

Type t;
string id;
ConstructorInfo ci = t.GetConstructor(new Type[] { });
object newob = ci.Invoke(null);
this.GetType().GetField(Id, System.Reflection.BindingFlags.FlattenHierarchy
| System.Reflection.BindingFlags.Instance).SetValue(this,newob);
 
B

bowser

Marc,

object id = ci.Invoke(null);

is incorrect because the type of 'id' is 'string'. (The compiler says:
"A local variable named 'id' cannot be declared in this scope because
it would give a different meaning to 'id', which is already used in a
'parent or current' scope to denote something else")

But that would be exactly what I wanted to do: create an object whose
name is the value of 'id'. For example if id="foo" and t="Foo", I want
to create an object 'Foo foo', that is: through reflection, I want to
get the equivalent of
Foo foo = Foo();

The right member ('Foo();') is translated as ...'ci.Invoke(null);'
but the left member remains a problem for me.

I hope I've been clear this time.

Thank you very much.

Alessandro
 
B

bowser

In the example I meant
Foo foo = new Foo();

I want to create the instance in a particular namespace, say 'ns',
which is not the one where I put the code under discussion.

Finally I recall the second problem: to check if 'foo' already exist
(whatever it's its type) given a namespace.
 

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