Two questions on C# classes

  • Thread starter Thread starter Pavils Jurjans
  • Start date Start date
P

Pavils Jurjans

Hello,

I have two separate questions on C# features, related with classes:

1.
Is there a way to store class references, say in array, or collection,
without creating an instance? I have an application that has a number of
"document" objects that are each a separate class that inherit from common
parent, "Document" class. In the application session, I may use only some of
these document classes, so I'd like to instantiate them only if there's a
need, and then I could use the instance until the end of session
(singleton). Currently I keep a hastable with single instance of every
document class and then refer to the requested one upon need. However, I am
worried that it's an ineffective way, since I take up memory with objects
that may never be used. Instead, I think, it would be more efficient, if I
could keep a hashtable with class references, and then instantiate object
only when needed. Something like this:

public class TxtDocClass : Document
{
....
}
.... more classes defined

Hashtable docClassLib = new Hashtable();
docClassLib.Add("txtDoc", TxtDocClass);
docClassLib.Add("docDoc", DocDocClass);
docClassLib.Add("xlsDoc", XlsDocClass);
// Instantiate one
class RequestedClass = docClassLib["xlsDoc"];
Document requestedDoc = new RequestedClass();

Of course, this is thought-out syntax, but maybe something like indirect
class reference is possible?

2.
Is there some way to walk over given namespace and take an instance of every
class that is defined in that namespace? This question is related to the
first one. If it is possible to find a way to store class references instead
of instances, I'd like to do that.

Thanks,

Pavils
 
Pavils Jurjans said:
Hello,

I have two separate questions on C# features, related with classes:

1.
Is there a way to store class references, say in array, or collection,
without creating an instance?

Of course, this is thought-out syntax, but maybe something like indirect
class reference is possible?

I think you're looking for the typeof() operator, which gives a Type
reference. You can then use that Type in Activator.CreateInstance, for
example.
2.
Is there some way to walk over given namespace and take an instance of every
class that is defined in that namespace? This question is related to the
first one. If it is possible to find a way to store class references instead
of instances, I'd like to do that.

You can find out all classes in a namespace within a particular
assembly, yes - just by finding all the types within the assembly, and
only "remembering" the ones which match the namespace you're interested
in. See Assembly.GetTypes for more information.
 
Cool, thanks a bunch.

P.

Jon Skeet said:
I think you're looking for the typeof() operator, which gives a Type
reference. You can then use that Type in Activator.CreateInstance, for
example.


You can find out all classes in a namespace within a particular
assembly, yes - just by finding all the types within the assembly, and
only "remembering" the ones which match the namespace you're interested
in. See Assembly.GetTypes for more information.
 
Jon said:
interested in. See Assembly.GetTypes for more information.

Hi Jon,

Just to piggy back on this thread, in an application that uses many
assemblies (9 or 10 plus) is there any way of getting all types from
all assemblies, including those that have not yet been loaded.

The specific issue I am having is looking for a class attribute
decorating a class, for registration into a factory object. The "fudge"
I am using at the moment is referencing the class and forcing the
assembly to be loaded, In itself not a big problem, but means that I
can't just add a new decorated class and have the registration code
pick it up, I have to alter the registration code as well.

Rgds Tim.
 
Tim Jarvis said:
Just to piggy back on this thread, in an application that uses many
assemblies (9 or 10 plus) is there any way of getting all types from
all assemblies, including those that have not yet been loaded.

The specific issue I am having is looking for a class attribute
decorating a class, for registration into a factory object. The "fudge"
I am using at the moment is referencing the class and forcing the
assembly to be loaded, In itself not a big problem, but means that I
can't just add a new decorated class and have the registration code
pick it up, I have to alter the registration code as well.

You can find all the currently loaded assemblies in the AppDomain with
AppDomain.GetAssemblies.

For each assembly, you can get the assemblies it references using
Assembly.GetReferencedAssemblies. You can then basically load the
transitive closure of all the assemblies involved, and then look at
them.

I wrote some primitive code to do the reference walking a while ago.
There may be some extra implications I'm unaware of, but it seems to
work. Do a groups.google.com search for a thread called
".NET Dependency Walker?" and you should find it.
 
Jon Skeet [C# MVP] wrote:

For each assembly, you can get the assemblies it references using
Assembly.GetReferencedAssemblies. You can then basically load the
transitive closure of all the assemblies involved, and then look at
them.

Aha, Thanks.

Rgds Tim.
 
Can I answer your question in 2 ways.

Firstly, you can store an array of class types.

e.g.
Type t = typeof(MyDocumentClass);

I'll let you decide the best way to store the t object. You can then
instanciate the classes perhapse using reflection or someother method
when needed.

e.g.
System.Type t = typeof(MyClass);
MyClass myClass = (MyClass)t.GetConstructors()[0].Invoke(new object[]
{"Hello"});

with

public class MyClass
{
public MyClass(string s)
{
Console.WriteLine(s);
}
}

Note: This could also be slow as reflection is slower than directly
manipulating objects/classes.

Secondly, for performance related issues I'd recommend you measure the
performance problem (where possible) instead of guessing what the
performance problem is.

i.e. I run my app and it runs too slow - so I imporve where I *think*
the bottleneck is, and (as always) I was wrong and I have imporoved
performance but not where it matters - so the app is still slow...

Adam
 
Back
Top