PC Review


Reply
Thread Tools Rate Thread

Can I use typeof() to make new objects?

 
 
Einar Værnes
Guest
Posts: n/a
 
      14th Dec 2006
Hi.
I am trying to programatically decide which type a new object should have,
but the typeof-function is apparently not the answer, as the following code
will not compile.

class AbstractClass:Object { }

class DerivedClass1 : AbstractClass { }

class DerivedClass2 : AbstractClass { }

static class Program
{
static void Main()
{
AbstractClass a,b,c;
a = new DerivedClass1();
b = new DerivedClass2();
if (some_condition)
c = new (typeof(a))();
else
c = new (typeof(b))();
}
}

How can implement this?

Best regards
Einar Værnes


 
Reply With Quote
 
 
 
 
=?ISO-8859-15?Q?Tobias_Schr=F6er?=
Guest
Posts: n/a
 
      14th Dec 2006
Hi,

Einar Værnes schrieb:
> Hi.
> I am trying to programatically decide which type a new object should have,
> but the typeof-function is apparently not the answer, as the following code
> will not compile.
>
> class AbstractClass:Object { }
>
> class DerivedClass1 : AbstractClass { }
>
> class DerivedClass2 : AbstractClass { }
>
> static class Program
> {
> static void Main()
> {
> AbstractClass a,b,c;
> a = new DerivedClass1();
> b = new DerivedClass2();
> if (some_condition)
> c = new (typeof(a))();
> else
> c = new (typeof(b))();
> }
> }
>
> How can implement this?


Take a look into the System.Reflection namespace. With typeof you will
get a Type object. The Assembly type has a CreateInstance method, which
will create a new object of a type:

AbstractClass myObject;
// ...
Type t = typeof(myObject);
Assembly a = Assembly.GetAssembly(t);
AbstractClass newObject = a.CreateInstance(t.FullName);
// ...

There are several signatures for Assembly::CreateInstance. So you can
pass arguments to the constructor, for example.


Btw and not concering your question, I find it confusing to have a class
that is named "AbstractClass" but is not declared abstract. But that
just a metter of "taste"

HTH,
Tobi
 
Reply With Quote
 
Marc Gravell
Guest
Posts: n/a
 
      14th Dec 2006
Well, you already created the instances? At a simple level, the
following should suffice:

AbstractClass c;
if(some_condition) {
c = new DerivedClass1();
} else {
c = new DerivedClass2();
}

There are other approaches:
* Activator.CreateInstance({various overloads})
* from reflection you can obtain and invoke the constructor
* you can use generics with the ": new() " (and perhaps " :
AbstractClass") clause(s)
* you can perhaps use a factory interface on existing instances

Can you explain a little more about the scenario, to identify a likely
candidate?

Note that typeof() works on type-definitions, not instances; in your
code you would use a.GetType() and b.GetType() to obtain the Type,
which can be used to create *additional* instances.


 
Reply With Quote
 
=?ISO-8859-15?Q?Tobias_Schr=F6er?=
Guest
Posts: n/a
 
      14th Dec 2006
Tobias Schröer schrieb:

> AbstractClass myObject;
> // ...
> Type t = typeof(myObject);
> Assembly a = Assembly.GetAssembly(t);
> AbstractClass newObject = a.CreateInstance(t.FullName);
> // ...


Argh, just saw an error:

Type t = myObject.GetType(); // not: Type t = typeof(myObject);

That would be correct, sorry.

Tobi

 
Reply With Quote
 
Einar Værnes
Guest
Posts: n/a
 
      14th Dec 2006
Thank you!
This did the job (with an additional typecast).

Einar Værnes

"Tobias Schröer" <tobias-(E-Mail Removed)> wrote in message
news:elr3li$c12$(E-Mail Removed)...
> Hi,
>
> Einar Værnes schrieb:
>> Hi.
>> I am trying to programatically decide which type a new object should
>> have,
>> but the typeof-function is apparently not the answer, as the following
>> code will not compile.
>>
>> class AbstractClass:Object { }
>>
>> class DerivedClass1 : AbstractClass { }
>>
>> class DerivedClass2 : AbstractClass { }
>>
>> static class Program
>> {
>> static void Main()
>> {
>> AbstractClass a,b,c;
>> a = new DerivedClass1();
>> b = new DerivedClass2();
>> if (some_condition)
>> c = new (typeof(a))();
>> else
>> c = new (typeof(b))();
>> }
>> }
>>
>> How can implement this?

>
> Take a look into the System.Reflection namespace. With typeof you will get
> a Type object. The Assembly type has a CreateInstance method, which will
> create a new object of a type:
>
> AbstractClass myObject;
> // ...
> Type t = typeof(myObject);
> Assembly a = Assembly.GetAssembly(t);
> AbstractClass newObject = a.CreateInstance(t.FullName);
> // ...
>
> There are several signatures for Assembly::CreateInstance. So you can pass
> arguments to the constructor, for example.
>
>
> Btw and not concering your question, I find it confusing to have a class
> that is named "AbstractClass" but is not declared abstract. But that just
> a metter of "taste"
>
> HTH,
> Tobi



 
Reply With Quote
 
=?ISO-8859-15?Q?Tobias_Schr=F6er?=
Guest
Posts: n/a
 
      14th Dec 2006
Einar Værnes schrieb:
> Thank you!
> This did the job (with an additional typecast).


yes, the CreateInstace return object must be casted )
You should add some exception handling around the code, especially, if
you create the object from a type name that is read from the configuration.

>
> Einar Værnes
>
> "Tobias Schröer" <tobias-(E-Mail Removed)> wrote in message
> news:elr3li$c12$(E-Mail Removed)...
>>
>>AbstractClass myObject;
>>// ...
>>Type t = myObject.GetType();
>>Assembly a = Assembly.GetAssembly(t);
>>AbstractClass newObject = a.CreateInstance(t.FullName);
>>// ...

AbstractClass newObject = (AbstractClass)a.CreateInstance(t.FullName);
 
Reply With Quote
 
Einar Værnes
Guest
Posts: n/a
 
      14th Dec 2006
Thanks for your answer, what I really want is to use a copy constructor,
like this:

public abstract class AbstractClass:Object { }

public class DerivedClass1 : AbstractClass
{
public DerivedClass1(){}
public DerivedClass1(AbstractClass a)
{
//some implementation
}
}

public class DerivedClass2 : AbstractClass
{
public DerivedClass2(){}
public DerivedClass2(AbstractClass a)
{
//some other implementation
}
}

static class Program
{
static void Main()
{
AbstractClass A = new DerivedClass2();

// Make a backup copy of object A (which in principle can have
any type derived from AbstractClass)
AbstractClass C = new (A.GetType())(A);
}
}


I can now (thanks to Tobias Schröer) create a new class of same type as A :
AbstractClass C =
(AbstractClass)Assembly.GetAssembly(A.GetType()).CreateInstance(A.GetType().FullName);
but this will not make a copy of object A, just a new object instance of the
same class as A.
Can I use CreateInstance to activate the copy constructor of the appropiate
class?


Best regards
Einar Værnes

"Marc Gravell" <(E-Mail Removed)> wrote in message
news:%(E-Mail Removed)...
> Well, you already created the instances? At a simple level, the following
> should suffice:
>
> AbstractClass c;
> if(some_condition) {
> c = new DerivedClass1();
> } else {
> c = new DerivedClass2();
> }
>
> There are other approaches:
> * Activator.CreateInstance({various overloads})
> * from reflection you can obtain and invoke the constructor
> * you can use generics with the ": new() " (and perhaps " :
> AbstractClass") clause(s)
> * you can perhaps use a factory interface on existing instances
>
> Can you explain a little more about the scenario, to identify a likely
> candidate?
>
> Note that typeof() works on type-definitions, not instances; in your code
> you would use a.GetType() and b.GetType() to obtain the Type, which can be
> used to create *additional* instances.
>
>



 
Reply With Quote
 
=?ISO-8859-15?Q?Tobias_Schr=F6er?=
Guest
Posts: n/a
 
      14th Dec 2006
Einar Værnes schrieb:
> Thanks for your answer, what I really want is to use a copy constructor,
> like this:

[..]
>
> I can now (thanks to Tobias Schröer) create a new class of same type as A :
> AbstractClass C =
> (AbstractClass)Assembly.GetAssembly(A.GetType()).CreateInstance(A.GetType().FullName);
> but this will not make a copy of object A, just a new object instance of the
> same class as A.
> Can I use CreateInstance to activate the copy constructor of the appropiate
> class?
>


See the System.IClonable interface and Object::MemberwiseClone(), that
should help.
Maybe you should google on cloning mechanisms. Depending on the data an
object contains (primitive or complex), some algorithms would be better
than others. E.g., serializing and deserializing an object can be used
for cloning.

Tobi
 
Reply With Quote
 
Marc Gravell
Guest
Posts: n/a
 
      14th Dec 2006
Since you seem to be calling the current type's own copy constructor
(i.e. if the type to be copied is "ClassA", you appear to be calling
"new ClassA(a)", how about just using a neatly typed ICloneable
implemenation?

using System;
public abstract class AbstractClass : ICloneable {
public AbstractClass Clone() { return DoClone(); }
object ICloneable.Clone() { return DoClone(); }
protected abstract AbstractClass DoClone();
}

public class DerivedClass1 : AbstractClass
{
public new DerivedClass1 Clone() { return
(DerivedClass1)DoClone(); }
protected override AbstractClass DoClone()
{
return null; // provide implementation
}
}

public class DerivedClass2 : AbstractClass
{
public new DerivedClass2 Clone() { return
(DerivedClass2)DoClone(); }
protected override AbstractClass DoClone()
{
return null; // provide implementation
}
}


 
Reply With Quote
 
Einar Værnes
Guest
Posts: n/a
 
      14th Dec 2006
It seems to get quite complicated to solve a apparently simple problem using
a copy constructor.

I have now moved the copy constructor code into a virtual
CloneFrom(AbstractClass a) - methode.
This implementation now does the job well enough for me:

namespace WindowsApplication1
{

public abstract class AbstractClass : Object
{
public int test_variable;
public abstract void CloneFrom(AbstractClass a);
}

public class DerivedClass1 : AbstractClass
{
public string teststring = "?";
public DerivedClass1() { test_variable = 1; }
public DerivedClass1(DerivedClass1 a) { CloneFrom(a); }
public override void CloneFrom(AbstractClass a)
{
DerivedClass1 c = (DerivedClass1)a;
test_variable = c.test_variable;
teststring = c.teststring;
}
}

static class Program
{
static void Main()
{
AbstractClass a;
a = new DerivedClass1();
a.test_variable = 100;
((DerivedClass1)a).teststring = "a";

// Make a backup copy of object a (which in principle can have
any type derived from AbstractClass)
AbstractClass d =
(AbstractClass)Assembly.GetAssembly(a.GetType()).CreateInstance(a.GetType().FullName);
d.CloneFrom(a);
((DerivedClass1)a).teststring = "a changed";
a.test_variable = 200; // Now test a.test_variable=200

// Restore a from backup
a.CloneFrom(d); // Now test a.test_variable=100
}
}

}


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Make ALL objects invisible? Henrootje Microsoft Access 3 23rd Dec 2005 12:03 PM
How to make objects disappear? Leo Bueno Microsoft Powerpoint 1 24th Sep 2005 05:01 PM
OOP and C#: Too much objects make me unhappy, but what can I do?? hufel Microsoft C# .NET 4 1st Mar 2005 05:23 PM
Should I make lots of objects? :-) Simon Microsoft C# .NET 5 22nd Dec 2004 07:32 PM
Re: How to make Office objects available to .NET C# Alan Microsoft C# .NET 1 19th Feb 2004 09:31 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 09:50 PM.