473,714 Members | 2,050 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Problems with IsSubclassOf

Hi all,

I'm building a user control in c#. This control has a property which
can contain an instance of a user defined class which has to be a
subclass of an abstract class A. I'd like the user of the control to be
able at design time to select the value of this property from a
dropdownlist showing all the subclasses of A that can be found in the
assemblies referenced in the project, so I wrote my own UITypeEditor
and at first everything seemed to be fine.
But then I noticed that the list in my editor displays only the
subclasses of A that are contained in assemblies which were referenced
before the control was added to the form, while it ignores the ones
contained in assemblies added after the creation of the control.
I found out that the even the classes contained in these late
assemblies are correctly identified by my code, but that the result of
the IsSubclassOf method is false instead of true.
This is a sample of what I'm doing (rs is an ITypeResolution Service):

Solution sol = currentDTE.Solu tion;
aList=new ArrayList();
foreach (Project prj in sol.Projects)
{
VSProject vsPrj=(VSProjec t) prj.Object;
References refs = vsPrj.Reference s;
foreach (Reference aRef in refs)
{
AssemblyName aName=new AssemblyName();
aName.Name=aRef .Name;
Assembly anAssembly=rs.G etAssembly(aNam e);
if (anAssembly!=nu ll)
{
Type[] types=anAssembl y.GetTypes();
foreach (Type t in types)
{
if (t.IsClass && !t.IsAbstract && t.IsSubclassOf( typeof(A)))
aList.Add(t.Ful lName);
}
}
}
}

Can you tell me what I'm doing wrong?

Many thanks,

Francesco.

Jan 17 '06 #1
9 3943
Paguro Bernardo wrote:
I'm building a user control in c#. This control has a property which
can contain an instance of a user defined class which has to be a
subclass of an abstract class A. I'd like the user of the control to be
able at design time to select the value of this property from a
dropdownlist showing all the subclasses of A that can be found in the
assemblies referenced in the project, so I wrote my own UITypeEditor
and at first everything seemed to be fine.


Do you have class A defined in multiple assemblies by any chance?
That's usually the problem.

Jon

Jan 17 '06 #2

Jon Skeet [C# MVP] ha scritto:
Paguro Bernardo wrote:
I'm building a user control in c#. This control has a property which
can contain an instance of a user defined class which has to be a
subclass of an abstract class A. I'd like the user of the control to be
able at design time to select the value of this property from a
dropdownlist showing all the subclasses of A that can be found in the
assemblies referenced in the project, so I wrote my own UITypeEditor
and at first everything seemed to be fine.


Do you have class A defined in multiple assemblies by any chance?
That's usually the problem.

Jon


Wow, faster than light!

It seems to me that class A is defined in just a single assembly, which
is referenced by three different assemblies: the one defining its
subclasses, the one defining the UITypeEditor, and the one defining the
user control. All these assemblies are located in the same directory,
and all of them are referenced in the project where I'm testing this
stuff. Can this be a problem?

Thanks again,
Francesco.

Jan 17 '06 #3
Paguro Bernardo wrote:
Do you have class A defined in multiple assemblies by any chance?
That's usually the problem.


It seems to me that class A is defined in just a single assembly, which
is referenced by three different assemblies: the one defining its
subclasses, the one defining the UITypeEditor, and the one defining the
user control. All these assemblies are located in the same directory,
and all of them are referenced in the project where I'm testing this
stuff. Can this be a problem?


So all the assemblies are in the same directory at runtime? That should
be okay.

Could you post a short but complete example which demonstrates the
problem?
See http://www.pobox.com/~skeet/csharp/complete.html for what I mean by
that.

You might want to go into the debugger having got both typeof(A) and
myType.BaseType into separate variables, and compare the two of them
for equality.

Jon

Jan 17 '06 #4
Jon Skeet [C# MVP] ha scritto:

So all the assemblies are in the same directory at runtime? That should
be okay.
Well, not exactly at runtime. I'm trying to add a control to a form at
design time, and the inheritance test is done when editing one of the
control properties.
Could you post a short but complete example which demonstrates the
problem?
See http://www.pobox.com/~skeet/csharp/complete.html for what I mean by
that.
For the time being I can't reach that URL because a stupid proxy
categorizes it as Health, and I'm not allowed to reach it from the
office. I'll take a look at it later and will will post the example.
You might want to go into the debugger having got both typeof(A) and
myType.BaseType into separate variables, and compare the two of them
for equality.

That's not so easy for me, since I'm quite a beginner and I'm not able
to debug this kind of things yet (debugging something at design time is
still black magic to me).

Francesco.

Jan 17 '06 #5
[Looks like my previous reply didn't make it - apologies if this shows
up twice]

Paguro Bernardo wrote:
So all the assemblies are in the same directory at runtime? That should
be okay.
Well, not exactly at runtime. I'm trying to add a control to a form at
design time, and the inheritance test is done when editing one of the
control properties.


Ouch. Okay - I don't know much about design-time stuff, I'm afraid.
Could you post a short but complete example which demonstrates the
problem?
See http://www.pobox.com/~skeet/csharp/complete.html for what I mean by
that.


For the time being I can't reach that URL because a stupid proxy
categorizes it as Health, and I'm not allowed to reach it from the
office. I'll take a look at it later and will will post the example.


Try going to http://www.yoda.arachsys.com/csharp/complete.html instead
- it's the same page, pobox.com is just a redirection service.
You might want to go into the debugger having got both typeof(A) and
myType.BaseType into separate variables, and compare the two of them
for equality.

That's not so easy for me, since I'm quite a beginner and I'm not able
to debug this kind of things yet (debugging something at design time is
still black magic to me).


In that case, I suggest you work out what the interesting information
might be, and make your class write it out to a log (preferrably a
plain text file somewhere, so it's easy to work out whether or not it's
working). It's a bit slow and painful, but may well be easier than
trying to do design-time debugging.

Jon

Jan 17 '06 #6
Paguro Bernardo wrote:
So all the assemblies are in the same directory at runtime? That should
be okay.

Well, not exactly at runtime. I'm trying to add a control to a form at
design time, and the inheritance test is done when editing one of the
control properties.


Ah. Okay, that's likely to be entirely different then. Hmm.
Could you post a short but complete example which demonstrates the
problem?
See http://www.pobox.com/~skeet/csharp/complete.html for what I mean by
that.


For the time being I can't reach that URL because a stupid proxy
categorizes it as Health, and I'm not allowed to reach it from the
office. I'll take a look at it later and will will post the example.


Try http://www.yoda.arachsys.com/csharp/complete.html - pobox.com is
just a redirector.
You might want to go into the debugger having got both typeof(A) and
myType.BaseType into separate variables, and compare the two of them
for equality.


That's not so easy for me, since I'm quite a beginner and I'm not able
to debug this kind of things yet (debugging something at design time is
still black magic to me).


That's understandable. I haven't done any design-time stuff at all, so
I'd probably be doing even worse.

You could cheat a little though - open a file and write log entries
with all the information you'd get from the debugger. It's a bit
painful, but should work.

Jon

Jan 17 '06 #7

Jon Skeet [C# MVP] ha scritto:
Try http://www.yoda.arachsys.com/csharp/complete.html - pobox.com is
just a redirector.

The redirector is OK, its yoda the "health" site. Anyway, in the
evening the damn thing is down, so I was able to reach your page. It's
always nice to meet another Catan's settler.

This is exactly what I'm trying to do:

I've got the following assemblies:
------------------------------------------------------------------------------------
the assembly MyBaseClass defining just the following class:

using System;

namespace MyBaseClass
{
public class BaseClass
{
public BaseClass()
{
}
}
}
------------------------------------------------------------------------------------
the assembly MyDerivedClasse s which references MyBaseClass and contains
2 derived classes: DerivedA and DerivedB:
using System;
using MyBaseClass;

namespace MyDerivedClasse s
{
public class DerivedA : BaseClass
{
public DerivedA()
{
}
}

public class DerivedB : BaseClass
{
public DerivedB()
{
}
}
}
--------------------------------------------------------------------------------------------------
the assembly MyTypeEditor, which references MyBaseClass and the System
assemblies System, System.Drawing. Design, System.Windows. Forms.Design,
System.Windows. Forms, System.Componen tModel.Design, System.Reflecti on,
EnvDTE, VSLangProj.
This assembly defines MyEditor as follows:

using System;
using System.Drawing. Design;
using System.Windows. Forms.Design;
using System.Windows. Forms;
using System.Componen tModel.Design;
using System.Reflecti on;
using EnvDTE;
using VSLangProj;
using MyBaseClass;
namespace MyTypeEditor
{
public class MyEditor : UITypeEditor
{
IWindowsFormsEd itorService edSvc;
ListBox lista;

public MyEditor()
{
}

public override UITypeEditorEdi tStyle GetEditStyle(
System.Componen tModel.ITypeDes criptorContext context)
{
return UITypeEditorEdi tStyle.DropDown ;
}

public override object
EditValue(Syste m.ComponentMode l.ITypeDescript orContext context,
System.IService Provider provider, object value)
{
ITypeResolution Service rs;
DTE currentDTE;

edSvc
=(IWindowsForms EditorService)p rovider.GetServ ice(typeof(IWin dowsFormsEditor Service));
rs =
(ITypeResolutio nService)contex t.GetService(ty peof(ITypeResol utionService));
currentDTE = (DTE)context.Ge tService(typeof (DTE));

Solution sol = currentDTE.Solu tion;
lista=new ListBox();
foreach (Project prj in sol.Projects)
{
VSProject vsPrj=(VSProjec t) prj.Object;
References refs = vsPrj.Reference s;
foreach (Reference aRef in refs)
{
if (!aRef.Name.Sta rtsWith("System "))
{
AssemblyName aName=new AssemblyName();
aName.Name=aRef .Name;
Assembly a=rs.GetAssembl y(aName);
if (a!=null)
{
Type[] types=a.GetType s();
foreach (Type t in types)
{// this MessageBox added to
understand what's happening at design time The problem occurs at this
point
MessageBox.Show (t.Name +" is
derived from BaseClass: " +
t.IsSubclassOf( typeof(BaseClas s)).ToString()) ;
if
(t.IsSubclassOf (typeof(BaseCla ss)))

lista.Items.Add (t.FullName);
}
}
}
}
}
try
{
lista.SelectedI ndexChanged +=new
EventHandler(li sta_SelectedInd exChanged);
edSvc.DropDownC ontrol(lista);
return lista.SelectedI tem;
}
catch
{
return value;
}
finally
{
lista.Dispose() ;
}
return value;
}

private void lista_SelectedI ndexChanged(obj ect sender,
EventArgs e)
{
if (edSvc != null) edSvc.CloseDrop Down();
}

}
}
-----------------------------------------------------------------------------------------------------------
Finally there is the assembly MyTestControl which defines the
TestControl UserControl (a very simple control containing only a
TextBox and a string property which uses MyEditor as UITypeEditor) and
references MyTypeEditor:

using System;
using System.Collecti ons;
using System.Componen tModel;
using System.Drawing;
using System.Data;
using System.Windows. Forms;
using System.Drawing. Design;
using TestListConvert er;

namespace MyTestControl
{
public class TestControl : System.Windows. Forms.UserContr ol
{
private String ps;

[Editor(typeof(U nEditor),typeof (UITypeEditor))]
public String s
{
get {return ps;}
set {ps = value;}
}

private System.Windows. Forms.TextBox textBox1;
private System.Componen tModel.Containe r components = null;

public TestControl()
{
InitializeCompo nent();
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Disp ose();
}
base.Dispose( disposing );
}

private void InitializeCompo nent()
{
this.textBox1 = new System.Windows. Forms.TextBox() ;
this.SuspendLay out();
this.textBox1.L ocation = new System.Drawing. Point(24,
16);
this.textBox1.N ame = "textBox1";
this.textBox1.T abIndex = 0;
this.textBox1.T ext = "textBox1";
this.Controls.A dd(this.textBox 1);
this.Name = "TestContro l";
this.Size = new System.Drawing. Size(144, 56);
this.ResumeLayo ut(false);
}
}
}

---------------------------------------------------------------------------------------------------

At this point I open a new Windows Application Project with references
to MyBaseClass and MyTestControl. At this point if I FIRST add a
reference to MyDerivedClasse s, and THEN add a TestControl to the form
everything seems to work fine when I try to set te s property of the
control using the editor. If I change the order of these steps (i.e. I
FIRST add the control, and THEN the reference) DerivedA and DerivedB
appear not to be derived from BaseClass.

Any idea?

Thanks again.

Francesco.

Jan 18 '06 #8
Paguro Bernardo wrote:

<snip>
At this point I open a new Windows Application Project with references
to MyBaseClass and MyTestControl. At this point if I FIRST add a
reference to MyDerivedClasse s, and THEN add a TestControl to the form
everything seems to work fine when I try to set te s property of the
control using the editor. If I change the order of these steps (i.e. I
FIRST add the control, and THEN the reference) DerivedA and DerivedB
appear not to be derived from BaseClass.

Any idea?


Hmm.. I wouldn't like to say for sure, to be honest. I suspect if you
delve deeper (using MessageBox.Show as a poor man's debugger) you'll
find it's loading the assembly containing BaseClass from different
places. However, I would suggest that as you've got a workaround, you
use that. It's probably simpler than trying to code around the problem.
Sorry not to give a more pleasant answer :(

Jon

Jan 18 '06 #9

Jon Skeet [C# MVP] ha scritto:

Hmm.. I wouldn't like to say for sure, to be honest. I suspect if you
delve deeper (using MessageBox.Show as a poor man's debugger) you'll
find it's loading the assembly containing BaseClass from different
places. However, I would suggest that as you've got a workaround, you
use that. It's probably simpler than trying to code around the problem.
Sorry not to give a more pleasant answer :(

I investigated a little more, but wasn't able to understand what's
happening. Since we are developing a framework which will be used by 50
programmers, it's quite important to have something which is always
working in the same way and not depending on the order in which things
are done. So I found out that if I don't pass the type of the
superclass directly to IsSuperclassOf, but instead use
ITypeResolution Service to get the assembly and then the type starting
from their names, everything seems to be OK. I don't like it too much,
but it can be considered accettable until I understand better were the
assemblies really come from.

Thanks for your help.

Francesco.

Jan 19 '06 #10

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

Similar topics

14
2320
by: Jim Hubbard | last post by:
Are you up to speed on the difficulties in using the 1.1 .Net framework? Not if you are unaware of the 1,596 issues listed at KBAlertz (http://www.kbalertz.com/technology_3.aspx). If you are going to use .Net......I highly recommend signing up for the free KBAlertz newsletter at http://www.kbalertz.com/default.aspx. Looking at all of the errors and quirks sometimes makes me wonder if this thing is really ready for prime time.
2
362
by: ME | last post by:
It appears that IsSubclassOf does not work. In the following example, why does typeof(IDerived).IsSubclassOf(typeof(IRoot)); yeild False when the IDerived interface DOES in fact derive from IRoot? The IsSubClassOf documentation states the following: "Determines whether the current Type derives from the specified Type" Wouldn't an interface be a Type? Basically I want to be able to look at an interface TYPE and determine if it is...
1
3046
by: 3f | last post by:
Hello; We have made a web application that people can download from our web site and installed on: Windows XP Windows 2000 Professional Windows 2003 Server Windows 2000 Server
5
8798
by: Corky | last post by:
This works: db2 SELECT DISTINCT PROBLEM_OBJECTS.PROBLEM_ID FROM PROBLEM_OBJECTS INNER JOIN PROBLEMS ON PROBLEM_OBJECTS.PROBLEM_ID = PROBLEMS.PROBLEM_ID WHERE INTEGER(DAYS(CURRENT DATE) - DAYS(PROBLEMS.CLOSE_DATE)) = 365 AND PROBLEMS.CLOSE_DATE IS NOT NULL But this doesn't: db2 SELECT DISTINCT PROBLEM_OBJECTS.PROBLEM_ID FROM PROBLEM_OBJECTS
10
2409
by: BBFrost | last post by:
We just recently moved one of our major c# apps from VS Net 2002 to VS Net 2003. At first things were looking ok, now problems are starting to appear. So far ... (1) ComboBox.SelectedValue = db_value; If the db_value was not included in the ComboBox value list the ComboBox.SelectedIndex used to return -1, Now the very same code is
3
4730
by: thomas | last post by:
Hi, I have three assemblies. In Assembly1 I define an abstract base class called MyBaseClass. In Assembly2 I derive a class from this MyBaseClass. If I asked in the derived class if this class is a sublass of MyBaseClass the function IsSubclassOf returns true, so this works properly. In the third assembly however, I don't get the right result when I ask for the subclass. My code looks as
1
3799
by: Mark R. Dawson | last post by:
A while ago there was a post where someone asked how to find if a type was derived from another type, three ways were mentioned: Solution1: if(derivedInstance.GetType().IsSubclassOf(typeof(BaseType))) { } Solution2: if(derivedType is BaseType)
0
1172
by: Rob | last post by:
Hello, I'm new to C# and have a question regarding factoring through reflection. I have a database filled with data represented by name and value pairs. Each name has a identically named class in my program. Each of these classes is a descendant of a 'DataType' class. After reading about reflection, I though I could use this naming in my advantage:
0
2244
by: Sergistm | last post by:
Hello World, :D I have a problem that it is making me crazy, I hope you can help me. I'm trying to execute a .exe file with the Procces.Start, and there is no problem when the file is on my computer, the problem comes when the file is in a network drive. The most amazing thing is that in one computer I can execute my .Net program without problems independently if the file is
0
8817
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9322
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9092
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9037
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7963
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4472
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4734
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3170
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2531
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.