C# 2.0/VS2005 inheritance reference problem

G

Guest

Hi,

I have the following problem with VS 2005 (Professional) and C# 2.0
I will use assembly and namespace synonymously here.

I have a class in namespace InheritClass inherit from a baseclass in
namespace BaseClass.
Then I have a class in namespace InheritClassUser that uses the class in
namespace InheritClass.
The references/using are from InheritClass to BaseClass and from
InheritClassUser to InheritClass
Why does it give the error:
Error 1 The type 'BaseClass.MyBaseClass' is defined in an assembly that is
not referenced. You must add a reference to assembly 'BaseClass,
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null'. D:\SOURCE\versuche\InheritanceReferenceProblem\InheritClassUser\MyInheritClassUser.cs 7 24 InheritClassUser


The code is as follows:
One Solution with:

Project 1 (Class Library):

namespace BaseClass
{
public class MyBaseClass
{
public MyBaseClass()
{

}

}
}
Project 2 (Class Library):

using BaseClass;
namespace InheritClass
{
public class MyInheritClass:MyBaseClass
{
public MyInheritClass():base()
{

}
}
}

Project 3 (Console Application):
using InheritClass;

namespace InheritClassUser
{
class MyInheritClassUser
{
MyInheritClass oMyInheritClass;

static void Main(string[] args)
{
}
}
}


This is strange, since from "intuition" MyInheritClassUser should not need
to know about MyBaseClass.
Why does it need a reference?
The reference from InheritClass to BaseClass should be enough to "find"
BaseClass.


Regards,
 
R

RCS

That error does make sense. When you consume MyInheritUserClass - that needs
(at runtime - although you will get an error at compile time too) to know
about BaseClass - because, after all - it's inherited from it.

Think of it this way, a "class" is nothing but "instructions" on how to
build an object. It's not actually an object itself. Think of a class as
blueprints for a house - it's not an actual house, it's just the
instructions for how to build a house.

So - when you declared that your class inherited from BaseClass, that's like
putting a note on your house blueprints that say "for directions on the
garage, go see page 5 of Bob's notebook". At the time when you are creating
your blueprints - that's fine.

When you go to create an instance of your class (you go to build a house,
based on the blueprints) - THAT is the time, when you need to actual go get
this information for real. So now you have a work-crew on site asking "Who
is this Bob character, where is his notebook and what is on Page 5? We need
to start building this house and now we actually need these directions!". So
my point is, when you inherit from another class - nothing happens when you
make that declaration - it doesn't need to know about the details of that
class at that moment. The moment of truth is when an object is about to be
created, based on the concrete class.. when it goes to construct this class,
it needs all the detailed information about it's base class - at runtime. So
you need to have, whereever that base class - ready and available (and
referenced).

Annnyyywwaayy... So yes, you need to make a "Reference" (Add Reference) -
from Project 2 to Project1 (if it's in the same solution) or the .dll that
project1 produces. And Project 3 would need to reference project 2 (because
project 2 already has a reference to project 1).

Hope that helps..


MSDNAndi said:
Hi,

I have the following problem with VS 2005 (Professional) and C# 2.0
I will use assembly and namespace synonymously here.

I have a class in namespace InheritClass inherit from a baseclass in
namespace BaseClass.
Then I have a class in namespace InheritClassUser that uses the class in
namespace InheritClass.
The references/using are from InheritClass to BaseClass and from
InheritClassUser to InheritClass
Why does it give the error:
Error 1 The type 'BaseClass.MyBaseClass' is defined in an assembly that is
not referenced. You must add a reference to assembly 'BaseClass,
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null'.
D:\SOURCE\versuche\InheritanceReferenceProblem\InheritClassUser\MyInheritClassUser.cs
7 24 InheritClassUser


The code is as follows:
One Solution with:

Project 1 (Class Library):

namespace BaseClass
{
public class MyBaseClass
{
public MyBaseClass()
{

}

}
}
Project 2 (Class Library):

using BaseClass;
namespace InheritClass
{
public class MyInheritClass:MyBaseClass
{
public MyInheritClass():base()
{

}
}
}

Project 3 (Console Application):
using InheritClass;

namespace InheritClassUser
{
class MyInheritClassUser
{
MyInheritClass oMyInheritClass;

static void Main(string[] args)
{
}
}
}


This is strange, since from "intuition" MyInheritClassUser should not need
to know about MyBaseClass.
Why does it need a reference?
The reference from InheritClass to BaseClass should be enough to "find"
BaseClass.


Regards,
 
G

Guest

Hi RCS,
Annnyyywwaayy... So yes, you need to make a "Reference" (Add Reference) -
from Project 2 to Project1 (if it's in the same solution) or the .dll that
project1 produces. And Project 3 would need to reference project 2 (because
project 2 already has a reference to project 1).
Unfortunately it does not help... if it were so easy, I would not have
posted it :)

So this is the scenario:
Project 2 references Project 1.
Project 3 references Project 2.

A class in Project 2 inherits from a class in Project 1.
Project 3 uses the derived class (based on the class in Project 1) from
Project 2

Project 3 complains that it does not have a reference to Project 1.

I kept the code as simple as possible so it is really easy to try it out...
I could offer to send the solution via email as a zip-file... however, it is
really simple as you can see.

So please have a second look at it.

Take care,
 
R

RCS

Oh, you are correct - that is correct, you DO need a reference to the
original class/library too. It does not compile the information from
Project1 into Project2.

What you describe is just "how it works" - I don't believe this is anything
that you can change, it's fundamental.
 
G

Guest

RCS said:
Oh, you are correct - that is correct, you DO need a reference to the
original class/library too. It does not compile the information from
Project1 into Project2.

What you describe is just "how it works" - I don't believe this is anything
that you can change, it's fundamental.

.... this is in case of several levels of inheritance quite bad :(
And it makes it pretty impossible to "hide" your internal code-strucure if
you do not want people to know what you are inheriting from.
I would have expected more from the compiler (I think it is a compiler/IDE
issue, since logically it is possible to follow the references from one
project to the other until you reach the base-class).

So, if it is "fundamental", it might well be fundamentally flawed.

I am sure someone will refer to that this is "by design" since you want to
use inheritance also "outside" the specific languages as part of the concepts
of .NET, however, it would be good to be able to define a "later"
starting-point for inheritance so that internally you can inherit from
classes that you do not need to "show" to the outside world, they exist.
 
R

RCS

Well, I guess I would ask - what do you expect to happen? If that base
functionality were compiled in, now you have versioning problems. If you
don't, then you have to have a copy of the base .dll.
 
G

Guest

RCS said:
Well, I guess I would ask - what do you expect to happen? If that base
functionality were compiled in, now you have versioning problems. If you
don't, then you have to have a copy of the base .dll.
Actually, since "having a copy of the base .dll" pretty much means that
during build of the inheriting dll the file has to be copied, it would not be
much better than compiling it in, unless you manually exchange the
"copied"-dll afterwards.
So, yes, I would opt for "compiling it in" for the scenarios I described.
In my scenario, you would not access the base .dll anyways, only through the
inherited dll. Sine a change in the inherited dll would mean a recompile, you
would get then the base dll of the version you want compiled in. So - no
versioning problems.
Other users of the base.dll would not see the version being compiled in the
derived dll.

Things that would not be allowed of course then are for example "casts" to
the base dll's types. But since this is not what my scenario has in mind,
this would not be an issue.

However, I see the versioning-complexity not much different between being
able to compile in and to have to use references...
 
S

Stefan Simek

It all comes from the fact that .NET doesn't support other than public
inheritance, so your projectt3 sees the project2 class as being
subclassed from project1 and it needs to know what exactly the class in
project1 is all about. If you really need to hide the implemenation from
project1, you have to embed the project1 class in your projec2 class.
This way, project3 will only need to reference project2.

As for the "compiling in", .net doesn't support any kind of static
compilation with dlls (nor does C++ AFAIK). You can use netmodules for
this kind of thing, but they are (god knows why) still not supported by
the IDE, so you would have to forget it and use the .NET SDK tools.

HTH,
Stefan
 
R

RCS

But you're missing one key element, if you were to put the base class in the
GAC, there would be only/exactly one copy of that DLL and that DOES fix your
versioning problem.
 
G

Guest

RCS said:
But you're missing one key element, if you were to put the base class in the
GAC, there would be only/exactly one copy of that DLL and that DOES fix your
versioning problem.
Umm... "my versioning problem".
Well, I do not necessarily want people to see the base class.
Furthermore... yes, there is only one copy of the DLL... however I prefer
having a copy of the DLL in a version I know in a location I control. I also
prefer copy-folder installation with applications as self contained as
possible.
Of course it all depends on what I want to achieve in the specific case.

(Yes, I know, as Stefan Simek reminded, .NET does not support non-public
inheritance, so I cannot avoid people to see the base class, but I am
interested in both, the concepts and what is actually possible.)
 

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