473,394 Members | 1,640 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,394 software developers and data experts.

Using .GetType() or similar to create object of arbitrary type...

....or, to put it perhaps more communicative, something like this:

Type someObjectsType = someObject.GetType();
someObjectsType newObject = new someObjectsType();

Is this possible? If so, how?

Thanks very much in advance,
Daniel :)

Mar 20 '06 #1
16 4730
<da********@gmail.com> wrote:
...or, to put it perhaps more communicative, something like this:

Type someObjectsType = someObject.GetType();
someObjectsType newObject = new someObjectsType();


You can use Activator.CreateInstance to create an object from its
type.

Eq.
Mar 20 '06 #2

Paul E Collins wrote:
<da********@gmail.com> wrote:
...or, to put it perhaps more communicative, something like this:

Type someObjectsType = someObject.GetType();
someObjectsType newObject = new someObjectsType();


You can use Activator.CreateInstance to create an object from its
type.

Eq.


Hi Paul :)

Thanks for your reply. Actually, I think I was a bit too generic in my
question. What's really happening is this... Consider these two
(simplified) classes:

public abstract class BaseClass
{
// A yet undefined item collection that can be of type
// "AppointmentCollection", "TaskCollection", or
// "ContactCollection", depending on what derived class
// is instantiated (PimItemCollection is the base type
// for all these):
protected PimItemCollection itemCollection;

public BaseClass(PimItemCollection itemCollection)
{
this.itemCollection = itemCollection;
}

}

public class TasksClass : BaseClass
{
// This derived class is supposed to handle tasks,
// so it passes a ref to a TaskCollection to the
// base class.
public TasksClass()
: base(new OutlookSession().Tasks.Items)
{
}
}

Okay, so one thing that the base class should be able to do, is provide
a "backup" (xml serialization) functionality of the items in a
TaskCollection, ContactCollection, or AppointmentCollection (which
contain objects of type PimItem : Task, PimItem : Contact, PimItem :
Appointment, respectively), without knowing the specific type up front.
Pulling out items as PimItem objects from the itemCollection works
fine, and I can create xml output from this without problem. But when I
need to restore, it's another deal. Perhaps because of widening casts
vs. narrowing casts?

Anyway, what I was hoping would work was the following. It's code
that's supposed to be in the base class:

// Detect the type of the items in the backup provider's
itemCollection:
System.Type itemType = itemCollection[0].GetType();

// Read backed up data into a new array:
XmlSerializer xmlSerializer = new
XmlSerializer(typeof(itemType[]));
StreamReader streamReader = new StreamReader(backupFile);
XmlTextReader xmlTextReader = new
XmlTextReader(streamReader);
itemType[] pimItems =
(itemType[])xmlSerializer.Deserialize(xmlTextReader);
xmlTextReader.Close();
streamReader.Close();
File.Delete(backupFile);

Here, I get a lot of errors saying, "The type or namespace name
'itemType' could not be found (are you missing a using directive or an
assembly reference?)"

So, basically, I don't really need to create a new object of the
unknown type, but I need to be able to use it like I'm stabbing at
above... Any ideas of how I could do something like that?

Thanks again,
Daniel :)

Mar 20 '06 #3
You can do this with Reflection.

Do you know Reflection?

Regards,
Lars-Inge Tønnessen
Mar 20 '06 #4
Hmm, okay.

As I understand it, when you write "typeof(itemType[])" that refers to
the type of an array of theoretical "itemType" objects. That is to
say, "itemType" is a type, but you can't stick square brackets on it
to get the equivalent type for an array of those. When you do that,
it's as though "itemType" was the class or struct name - hence the
errors you're seeing about an unknown type name.

If that's true, then the question is how we get from a scalar Type
like typeof(string) to the corresponding 1D array type like
typeof(string[]). I can't see anything in the Type class that would
help with this, unfortunately. Anybody else have bright ideas?

Eq.
Mar 20 '06 #5
Paul E Collins wrote:
Hmm, okay.

As I understand it, when you write "typeof(itemType[])" that refers to
the type of an array of theoretical "itemType" objects. That is to
say, "itemType" is a type, but you can't stick square brackets on it
to get the equivalent type for an array of those. When you do that,
it's as though "itemType" was the class or struct name - hence the
errors you're seeing about an unknown type name.

If that's true, then the question is how we get from a scalar Type
like typeof(string) to the corresponding 1D array type like
typeof(string[]). I can't see anything in the Type class that would
help with this, unfortunately. Anybody else have bright ideas?

Eq.

Not 100% bullet proofed, but might work for you:

int[] ints = new int[] { };
Type tp = ints.GetType();
Type arrayType;
if(tp.IsArray)
arrayType = tp.GetElementType();
HTH,
Andy

--
To email me directly, please remove the *NO*SPAM* parts below:
*NO*SPAM*xmen40@*NO*SPAM*gmx.net
Mar 20 '06 #6
Paul E Collins <fi******************@CL4.org> wrote:
If that's true, then the question is how we get from a scalar Type
like typeof(string) to the corresponding 1D array type like
typeof(string[]). I can't see anything in the Type class that would
help with this, unfortunately. Anybody else have bright ideas?


You can put the "[]" on the end of the type name, then use
Assembly.GetType (using the assembly which supplies the type itself).
Bit of a hack but it works.

Better, if you're using .NET 2.0, is to use the Type.MarkArrayType()
method.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 20 '06 #7

Jon wrote:
Paul E Collins <fi******************@CL4.org> wrote:
If that's true, then the question is how we get from a scalar Type
like typeof(string) to the corresponding 1D array type like
typeof(string[]). I can't see anything in the Type class that would
help with this, unfortunately. Anybody else have bright ideas?
You can put the "[]" on the end of the type name, then use
Assembly.GetType (using the assembly which supplies the type itself).
Bit of a hack but it works.


Care to add an example? I don't quite understand what you mean, and
I've been trying to add brackets here and there, and using different
combos of Assembly.GetType, but all the time with errors... :)
Better, if you're using .NET 2.0, is to use the Type.MarkArrayType()
method.

Actually, and sorry for not saying this before, it's .NET Compact
Framework 2.0. Is that a problem? I couldn't find the MarkArrayType()
method on Type...
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


Mar 20 '06 #8

Andy wrote:
Not 100% bullet proofed, but might work for you:

int[] ints = new int[] { };
Type tp = ints.GetType();
Type arrayType;
if(tp.IsArray)
arrayType = tp.GetElementType();


This is closer (at least compiler-wise ;), but not quite there. I tried
this:

// Get the type of the items in the itemCollection:
Type itemType = itemCollection.GetType();
Type arrayType = itemType.GetElementType();

// Get the dump of tasks from the server:
connection.RestoreItem(store, collection, tmpFile);

// Read into a new object (TODO: Get rid of immensely ugly
and huge if-else structure - need to crack casting/GetType() nut):
XmlSerializer xmlSerializer = new XmlSerializer(arrayType);
StreamReader streamReader = new StreamReader(tmpFile);
XmlTextReader xmlTextReader = new
XmlTextReader(streamReader);
* arrayType pimItems =
(arrayType)xmlSerializer.Deserialize(xmlTextReader );
xmlTextReader.Close();
streamReader.Close();
File.Delete(tmpFile);

But still get the previously mentioned error on the line marked with an
asterisk...
HTH,
Andy

--
To email me directly, please remove the *NO*SPAM* parts below:
*NO*SPAM*xmen40@*NO*SPAM*gmx.net


Mar 20 '06 #9

Paul E Collins wrote:
Hmm, okay.

As I understand it, when you write "typeof(itemType[])" that refers to
the type of an array of theoretical "itemType" objects. That is to
say, "itemType" is a type, but you can't stick square brackets on it
to get the equivalent type for an array of those. When you do that,
it's as though "itemType" was the class or struct name
Exactly. That's what I would like it to be :) Just don't know how to
get there... Right now it's a very ugly and very big if-else until (if)
I figure it out...
- hence the
errors you're seeing about an unknown type name.

If that's true, then the question is how we get from a scalar Type
like typeof(string) to the corresponding 1D array type like
typeof(string[]). I can't see anything in the Type class that would
help with this, unfortunately. Anybody else have bright ideas?

Eq.


Mar 20 '06 #10

Lars-Inge Tønnessen (VJ# MVP) wrote:
You can do this with Reflection.

Do you know Reflection?

No, not really. I came by a few pages scouring google, but all were
about listing properties and methods of objects, so I thought it was a
detour. Could you show me how?
Regards,
Lars-Inge Tønnessen


Mar 20 '06 #11
<da********@gmail.com> wrote:
You can put the "[]" on the end of the type name, then use
Assembly.GetType (using the assembly which supplies the type itself).
Bit of a hack but it works.


Care to add an example? I don't quite understand what you mean, and
I've been trying to add brackets here and there, and using different
combos of Assembly.GetType, but all the time with errors... :)


Try this:

using System;
using System.IO;

class Test
{
static void Main()
{
Console.WriteLine (MakeArrayType (typeof(object)));
Console.WriteLine (MakeArrayType (typeof(string)));
Console.WriteLine (MakeArrayType (typeof(Stream)));
Console.WriteLine (MakeArrayType (typeof(IDisposable)));
}

static Type MakeArrayType (Type t)
{
string arrayName = t.FullName+"[]";
return t.Assembly.GetType(arrayName);
}
}

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 21 '06 #12

Jon wrote:
<da********@gmail.com> wrote:
You can put the "[]" on the end of the type name, then use
Assembly.GetType (using the assembly which supplies the type itself).
Bit of a hack but it works.


Care to add an example? I don't quite understand what you mean, and
I've been trying to add brackets here and there, and using different
combos of Assembly.GetType, but all the time with errors... :)


Try this:

using System;
using System.IO;

class Test
{
static void Main()
{
Console.WriteLine (MakeArrayType (typeof(object)));
Console.WriteLine (MakeArrayType (typeof(string)));
Console.WriteLine (MakeArrayType (typeof(Stream)));
Console.WriteLine (MakeArrayType (typeof(IDisposable)));
}

static Type MakeArrayType (Type t)
{
string arrayName = t.FullName+"[]";
return t.Assembly.GetType(arrayName);
}
}


Hi again :)

I'm still unable to use this like I want... Consider this:

Type pimArrayType = MakeArrayType(itemCollection[0].GetType());
// Some code...
pimArrayType pimItems =
(pimArrayType)xmlSerializer.Deserialize(xmlTextRea der);

This last instruction fails with, "The type or namespace name
'pimArrayType ' could not be found (are you missing a using directive
or an assembly reference?)"

Any ideas?

Mar 21 '06 #13
da********@gmail.com wrote:
I'm still unable to use this like I want... Consider this:

Type pimArrayType = MakeArrayType(itemCollection[0].GetType());
// Some code...
pimArrayType pimItems =
(pimArrayType)xmlSerializer.Deserialize(xmlTextRea der);

This last instruction fails with, "The type or namespace name
'pimArrayType ' could not be found (are you missing a using directive
or an assembly reference?)"

Any ideas?


You can't use types like that - the type of pimItems has to be known at
compile time, and it isn't with your code.

Now, what's the context here? What were you planning on doing with
pimItems anyway?

Jon

Mar 21 '06 #14

Jon Skeet [C# MVP] wrote:
da********@gmail.com wrote:
I'm still unable to use this like I want... Consider this:

Type pimArrayType = MakeArrayType(itemCollection[0].GetType());
// Some code...
pimArrayType pimItems =
(pimArrayType)xmlSerializer.Deserialize(xmlTextRea der);

This last instruction fails with, "The type or namespace name
'pimArrayType ' could not be found (are you missing a using directive
or an assembly reference?)"

Any ideas?
You can't use types like that - the type of pimItems has to be known at
compile time, and it isn't with your code.


Damn :'(
Now, what's the context here? What were you planning on doing with
pimItems anyway?

Well, the hope was to use a generic function in the baseclass that
could support backing up and restoring these different subtypes
(Appointment, Task, Contact) of the PimItem supertype/superclass. It's
easy to back up, because I can treat the objects as PimItems and
serialize them that way. Problem comes when I try to restore - going
from PimItem back to a derived type throws an invalid cast exception...
So right now I have a big if-else structure that restores everything
differently depending on the type needed.
Jon


Mar 21 '06 #15
<da********@gmail.com> wrote:
Now, what's the context here? What were you planning on doing with
pimItems anyway?


Well, the hope was to use a generic function in the baseclass that
could support backing up and restoring these different subtypes
(Appointment, Task, Contact) of the PimItem supertype/superclass. It's
easy to back up, because I can treat the objects as PimItems and
serialize them that way. Problem comes when I try to restore - going
from PimItem back to a derived type throws an invalid cast exception...
So right now I have a big if-else structure that restores everything
differently depending on the type needed.


Serialization should do this for you automatically though. It's not
entirely clear where the problem is.

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. In this case, it should show two of your types.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 21 '06 #16

Jon wrote:
<da********@gmail.com> wrote:
Well, the hope was to use a generic function in the baseclass that
could support backing up and restoring these different subtypes
(Appointment, Task, Contact) of the PimItem supertype/superclass. It's
easy to back up, because I can treat the objects as PimItems and
serialize them that way. Problem comes when I try to restore - going
from PimItem back to a derived type throws an invalid cast exception...
So right now I have a big if-else structure that restores everything
differently depending on the type needed.
Serialization should do this for you automatically though. It's not
entirely clear where the problem is.


I think the problem is that it's easy enough to cast when you can
write:
Task aTask = (Task)pimItems[0];

....but what I need to do is something like this:
Type itemType = pimItems[0].GetType()
itemType aTask = (itemType)pimItems[0];

It's logically (human logic) the same thing, but this usage of itemType
is not allowed, or just misunderstood (or probably both ;) I just need
some approach to creating a generic version of this...
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. In this case, it should show two of your types.


I read it, but it's gonna be difficult. I'm using two assemblies, one
of which provides the PimItem and friends. This is a program for a
school assignment, and I'm actually done with it, settling for the
if-else approach, right now I'm writing documentation. But if you're
interested, I could mail you the entire project which compiles and is
extensively documented. My e-mail here isn't fake, so just mail me if
you'd like to see it :)

Thanks for your time!

Daniel

Mar 24 '06 #17

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

Similar topics

2
by: Will Lusted | last post by:
Can anyone give me a pointer as where I'm going wrong? I'm building a base class that persists to a database using serialization. GetDoc() is a base class function that reads back XML to...
2
by: JohnnySparkles | last post by:
Hi everyone, I'm currently writing an application which uses the XmlSerializer class to serialize/deserialize objects to/from xml. Now when deserializing an XmlDocument back into the object,...
0
by: samlee | last post by:
Hi All, I'm learning how to write C# using reflection, but don't know how to code using reflection this.Controls.Add(this.label1); Could anyone help, Thank in advance. ...
0
by: Simon Gregory | last post by:
I'm trying to override the default elementnames in the (seemingly) simple case of serializing an array of GUIDs into XML. Here's the basic code I started with: Dim arrGuids(3) as Guid ...
5
by: Matthew | last post by:
I have a nice little Sub that saves data in a class "mySettings" to an XML file. I call it like so: Dim mySettings As mySettings = New mySettings mySettings.value1 = "someText" mySettings.value2...
13
by: Don | last post by:
How do I get an Enum's type using only the Enum name? e.g. Dim enumType as System.Type Dim enumName as String = "MyEnum" enumType = ???(enumName)
6
by: ransoma22 | last post by:
I developing an application that receive SMS from a connected GSM handphone, e.g Siemens M55, Nokia 6230,etc through the data cable. The application(VB.NET) will receive the SMS automatically,...
53
by: Hexman | last post by:
Hello All, I'd like your comments on the code below. The sub does exactly what I want it to do but I don't feel that it is solid as all. It seems like I'm using some VB6 code, .Net2003 code,...
5
by: raylopez99 | last post by:
I have a form, Form6, that has a bunch of buttons overlaid on it. I want to be able to click on any arbitrary area of the form, and if that area of the form is overlaid by a button, I want to...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

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.