473,378 Members | 1,140 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Can I use typeof() to make new objects?

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
Dec 14 '06 #1
11 12778
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
Dec 14 '06 #2
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.
Dec 14 '06 #3
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

Dec 14 '06 #4
Thank you!
This did the job (with an additional typecast).

Einar Værnes

"Tobias Schröer" <to*******************@gmx.dewrote in message
news:el**********@news.citykom.de...
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

Dec 14 '06 #5
Einar Værnes schrieb:
Thank you!
This did the job (with an additional typecast).
yes, the CreateInstace return object must be casted :o)
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" <to*******************@gmx.dewrote in message
news:el**********@news.citykom.de...
>>
AbstractClass myObject;
// ...
Type t = myObject.GetType();
Assembly a = Assembly.GetAssembly(t);
AbstractClass newObject = a.CreateInstance(t.FullName);
// ...
AbstractClass newObject = (AbstractClass)a.CreateInstance(t.FullName);
Dec 14 '06 #6
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()).C reateInstance(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" <ma**********@gmail.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
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.


Dec 14 '06 #7
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()).C reateInstance(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
Dec 14 '06 #8
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
}
}
Dec 14 '06 #9
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()).C reateInstance(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
}
}

}
Dec 14 '06 #10
"Einar Værnes" <no*****@hotmail.coma écrit dans le message de news:
eF*************@TK2MSFTNGP06.phx.gbl...

| Thank you!
| This did the job (with an additional typecast).

Einar

I really would recommend that you use the Clone method rather than using
reflection, there can be quite a speed difference if you need to create lots
of objects.

public abstract class Base : ICloneable
{
public abstract object Clone();
}

public class DerivedClass1 : Base
{
public override object Clone()
{
return new DerivedClass1();
}
}
public class DerivedClass2 : Base
{
public override object Clone()
{
return new DerivedClass2();
}
}

static class Program
{
static void Main()
{
Base a,b,c;

a = new DerivedClass1();

b = new DerivedClass2();

if (some_condition)
c = (Base) a.Clone();
else
c = (Base) b.Clone();
}
}

This is known as the Prototype pattern and is very useful for fast creation
of instances based on a prototype instance.

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Dec 14 '06 #11
"Joanna Carter [TeamB]" <jo****@not.for.spama écrit dans le message de
news: %2****************@TK2MSFTNGP02.phx.gbl...

| I really would recommend that you use the Clone method rather than using
| reflection, there can be quite a speed difference if you need to create
lots
| of objects.

I forgot that this can also help with using a copy constructor :

public class DerivedClass1 : Base
{
public DerivedClass1(DerivedClass1 other)
{
// copy private members from other
}

public override object Clone()
{
return new DerivedClass1(this);
}
}

public class DerivedClass2 : Base
{
public DerivedClass2(DerivedClass2 other)
{
// copy private members from other
}

public override object Clone()
{
return new DerivedClass2(this);
}
}

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Dec 14 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Robert Mark Bram | last post by:
Hi All! I have the following code in an asp page whose language tag is: <%@LANGUAGE="JAVASCRIPT" CODEPAGE="65001"%> // Find request variables. var edition = Request.Form ("edition"); var...
3
by: James Marshall | last post by:
I need to detect the type of an object, more than just "object" as typeof gives us. I'm writing a general handler that accepts a variety of objects and properties, and acts accordingly depending...
7
by: Bennett Haselton | last post by:
Is there any way to find a string representing an object's class, which will work in Internet Explorer 6? "typeof" doesn't work -- it returns "object" for all objects: x =...
4
by: rua17 | last post by:
Hello: I want to know if somo variable is integer, real or string but typeof returns Int16, Int32, etc, because of that my if() statement has to compare if X is Int32 or Int64 or ... Any idea...
9
by: Klaus Johannes Rusch | last post by:
IE7 returns "unknown" instead of "undefined" when querying the type of an unknown property of an object, for example document.write(typeof window.missingproperty); Has "unknown" been defined...
4
by: EManning | last post by:
Using A2003. I've got an option group that has a number of check boxes. I have coding to clear the option group if the user wishes to cancel their choice. This coding also clears the rest of the...
20
by: effendi | last post by:
I am testting the following code in firefox function fDHTMLPopulateFields(displayValuesArray, displayOrderArray) { var i, currentElement, displayFieldID, currentChild, nDisplayValues =...
11
by: -Lost | last post by:
I have this generic function (JavaScript newbie here, so don't think I am going to impress you): function blah() { var container = ''; for(var i = 0; i < arguments.length; i++) { container...
3
by: phocis | last post by:
I wrote a pair of functions to enable scoped or referenced setTimeout calls. I did this because I have an object factory that creates multiple objects and those objects need to delay a few calls on...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.