Finding all child classes.

A

Allan Ebdrup

I would like to use reflection to find all classes that inherit from my
current class, even if they are in another assembly I want to find them if
the current project has a reference to that assembly.
The reason for this is that I want to check some attributes of all child
classes and have the base class react to this information in the child
classes.

Is this possible in an easy way, or do I have to traverse all loaded
assemblies and all their classes to find the child classes?

Kind Regards,
Allan Ebdrup
 
J

Jon Skeet [C# MVP]

Allan Ebdrup said:
I would like to use reflection to find all classes that inherit from my
current class, even if they are in another assembly I want to find them if
the current project has a reference to that assembly.
The reason for this is that I want to check some attributes of all child
classes and have the base class react to this information in the child
classes.

Is this possible in an easy way, or do I have to traverse all loaded
assemblies and all their classes to find the child classes?

You can find all referenced assemblies (recursively) with
Assembly.GetReferencedAssemblies.

You can find all the types within a type with Assembly.GetTypes, and
you can check type relations with Type.IsSubclassOf.
 
A

Allan Ebdrup

Jon Skeet said:
You can find all referenced assemblies (recursively) with
Assembly.GetReferencedAssemblies.

Say my base class is in assembly A and I have a child class in assembly B
Now I have a project that references A and B, how do I write code in my base
class so that it can see that there is a child class in Assembly B
Is it just Assembly.GetReferencedAssemblies? If I write that in assembly A
will that not just get the assemblies referenced from A? Or will
Assembly.GetReferencedAssemblies be evaluated at runtime to get all
referenced assemblies for the current running assembly?

Kind Regards,
Allan Ebdrup
 
J

Jon Skeet [C# MVP]

Allan Ebdrup said:
Say my base class is in assembly A and I have a child class in assembly B
Now I have a project that references A and B, how do I write code in my base
class so that it can see that there is a child class in Assembly B
Is it just Assembly.GetReferencedAssemblies? If I write that in assembly A
will that not just get the assemblies referenced from A? Or will
Assembly.GetReferencedAssemblies be evaluated at runtime to get all
referenced assemblies for the current running assembly?

You'd have to call it on assembly C (the assembly that references A and
B). You can get the currently executing assembly with

Assembly.GetExecutingAssembly()
 
J

Joanna Carter [TeamB]

"Allan Ebdrup" <[email protected]> a écrit dans le message de eFRel%[email protected]...

|I would like to use reflection to find all classes that inherit from my
| current class, even if they are in another assembly I want to find them if
| the current project has a reference to that assembly.
| The reason for this is that I want to check some attributes of all child
| classes and have the base class react to this information in the child
| classes.

This really isn't necessary; this is the kind of thing that virtual methods
are there for.

public class BaseClass
{
private void CheckAttributes()
{
// setup parameters to pass to virtual method
HandleAttribute(/* params passed in*/);
// examine params and react
}

protected virtual void HandleAttribute(/*params from base class*/)
{
// ...
}
}

class DerivedClass
{
protected override void HandleAttribute(/*params from base class*/)
{
// ...
}
}

Joanna
 
J

Jeffrey Tan[MSFT]

Hi Allan,

Thanks for your feedback.

Yes, in this scenario, there is no direct reference relationship between
assembly A and B, so Assembly.GetReferencedAssemblies() called in assembly
A will not find assembly B.

The solution is using Assembly.GetEntryAssembly() method to get the first
root assembly(Exe) reference, and then recursively loop through all its
referenced assemblies Assembly.GetReferencedAssemblies(). Note1 : the
assembly A and B may not be directly referenced by the Exe, so you may need
to recursively loop through all the referenced assemblies again.
Note2 : during the recursively loop, you should take care of the redundant
assemblies checking, so that once an assembly is checked, it will not be
checked in the further loop and search.

Additionally, I am not sure your problem context. Have you considered to
use virtual function and polymorphism to resolve this problem as Joanna
pointed out? This may be more suitable solution.

If you have anything unclear or need any help, please feel free to
feedback. Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
A

Allan Ebdrup

Joanna Carter said:
"Allan Ebdrup" <[email protected]> a écrit dans le message de eFRel%[email protected]...

|I would like to use reflection to find all classes that inherit from my
| current class, even if they are in another assembly I want to find them
if
| the current project has a reference to that assembly.
| The reason for this is that I want to check some attributes of all child
| classes and have the base class react to this information in the child
| classes.

This really isn't necessary; this is the kind of thing that virtual
methods
are there for.

public class BaseClass
{
private void CheckAttributes()
{
// setup parameters to pass to virtual method
HandleAttribute(/* params passed in*/);
// examine params and react
}

protected virtual void HandleAttribute(/*params from base class*/)
{
// ...
}
}

class DerivedClass
{
protected override void HandleAttribute(/*params from base class*/)
{
// ...
}
}

Joanna

Hi Joanna
The code i'm implementing is a attribute driven Object Relational Manager,
Based on the attributes I want to create objectes that correspond to some
type value stored in the database. I want to implement this functionality
only once in the base class but I want it to be able to construct the right
child class based on the type value stored in the database, therfore the
base class needs access to all it's child classes.
It's somewhat advanced and makes heavy use of reflection, but a virtual
function is not an option.

A bit more detail:

Say I have class A that has a constuctor that takes an id (int) that
correspond to a primary key in the database
In class B I have the following

public class B : Databinder<int>
{
[BindObject]
A _a
}

Suppose I have an instance og the B class in the variable b.
Now my databinder will save the _a objects id in the database when I persist
b whit the record for b
When I load b again my databinder constructs an instance of the A class and
puts it in _a automatically.

Now suppose I have a class C that inherits from A that I put an instance of
it in _a and save b again. When I load b again I want it to constunct an
instance of C not A, therefore I need a mechanism to construct the right
child class, this is where the need to find all child classes comes in,
because in the attributes of C I can see when to construct a C instance. I
could put this information in the base class but that wouldn't be very
composable, I don't want to have to change the base class every time I
inherit form it.

The databinder can do a lot of things and would take a lot of time to
explain in detail, but makes it so that I hardly have to write any SQL
code, it's all generated for me automatically. All I have to do is add
attributes to my class, and all the loading and persisting of objects it
there.

Kind Regards,
Allan Ebdrup
 
A

Allan Ebdrup

"Jeffrey Tan[MSFT]" said:
Yes, in this scenario, there is no direct reference relationship between
assembly A and B, so Assembly.GetReferencedAssemblies() called in assembly
A will not find assembly B.

The solution is using Assembly.GetEntryAssembly() method to get the first
root assembly(Exe) reference, and then recursively loop through all its
referenced assemblies Assembly.GetReferencedAssemblies(). Note1 : the
assembly A and B may not be directly referenced by the Exe, so you may
need
to recursively loop through all the referenced assemblies again.
Note2 : during the recursively loop, you should take care of the
redundant
assemblies checking, so that once an assembly is checked, it will not be
checked in the further loop and search.

Thanks for the pointers I will do that.

I found a recommendation to use:
type.IsAssignableFrom(myType)
To see if a specific type is a child class og myType, would you agree that
this is the best way to do it?
Additionally, I am not sure your problem context. Have you considered to
use virtual function and polymorphism to resolve this problem as Joanna
pointed out? This may be more suitable solution.

Se my answer to Joanna why a virtual function is not an option.

Kind Regards,
Allan Ebdrup.
 
J

Jeffrey Tan[MSFT]

Hi Allan ,

The difference between IsAssignableFrom and IsSubclassOf normally comes
from the interface area. IsSubclassOf method can not be used to determine
if an interface is and child interface of another interface. If you are
only dealing with class types without interface, IsSubclassOf is enough for
you, see the blog below:
"Using IsSubclassOf on an Interface type"
http://dotnetjunkies.com/WebLog/johnwood/archive/2006/01/21/134854.aspx

Also, thank you for sharing the detailed context information regarding your
application.

Anyway, if you still need any help, please feel free to tell me, thanks.

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Allan ,

Have you reviewed my last reply to you? Does it make sense to you? If you
still need any help or have any concern, please feel free to feedback,
thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 

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