Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / March 2006

Tip: Looking for answers? Try searching our database.

DotNet wants references that I'm not using

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Michael Brooks - 15 Mar 2006 22:25 GMT
I'm using dotNet V1.1, C# .

I create a class library as follows:

using System;
using System.Web.UI.WebControls;
using System.Windows.Forms;

namespace ClassLibrary1
{
    public class Class1
    {
        public Class1()
        {
        }

        public static void SetVar(ref System.Web.UI.WebControls.TextBox reportVar)
        {
        }

        public static void SetVar(ref System.Windows.Forms.TextBox reportVar)
        {
        }
    }
}

I have created this library so that it can be used by both Windows Forms and
Web applications - see the overloaded forms of the SetVar() method. This
class library compiles successfully.

I then create a Windows Forms application with a reference to this class
library. The relevant snippets are below:

using ClassLibrary1;
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace WindowsApplication1
{
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button goButton;
        private System.Windows.Forms.TextBox textBox1;

// Usual VS-inserted stuff goes here, and my own method to respond
// to clicking on a button is shown below.

        private void goButton_Click(object sender, System.EventArgs e)
        {
            Class1.SetVar(ref textBox1);
        }
    }
}

So, my application is a Windows application making use of my class.

When I compile this, I get the following error.

error CS0012: The type 'System.Web.UI.WebControls.TextBox' is defined in an
assembly that is not referenced. You must add a reference to assembly
'System.Web'.

Why is this happening? Surely my application should only need to reference
the assemblies that provide the classes that it actually makes use of? I'm
pretty sure that with C/C++ I wouldn't have had to link against a static
library that I wasn't using, even if another library that I was using had a
function that used a type from the unlinked library. I can't find anything in
the C# specification that explains this behaviour.

More importantly, how do I fix this so that my Windows Forms application
does not have to reference System.Web?
Mattias Sjögren - 15 Mar 2006 22:44 GMT
Michael,

>Why is this happening?

The compiler needs it to be referenced so it can get the whole picture
of the type you're using.

>More importantly, how do I fix this so that my Windows Forms application
>does not have to reference System.Web?

Is it really a big deal? As long as you don't use anything from the
assembly it will not be required at runtime.

Mattias

Signature

Mattias Sjögren [C# MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Michael Brooks - 15 Mar 2006 23:20 GMT
> Is it really a big deal? As long as you don't use anything from the
> assembly it will not be required at runtime.

Thanks Mattias. Unfortunately I think it does matter in this case. I am
encountering this problem in a class library that I intend to make available
to customers. I think a customer would be very confused and annoyed at having
to remember to make their Windows applications include a reference to the Web
assembly and vice versa. If I rename my methods so that they are not
overloading each other, that gets around the issue but makes a mess of the
class from the developer's perspective - the developer should only have to
remember one method regardless of the type that he is passing in. Surely
there must be some way around this?
Jon Skeet [C# MVP] - 16 Mar 2006 00:22 GMT
> > Is it really a big deal? As long as you don't use anything from the
> > assembly it will not be required at runtime.
[quoted text clipped - 8 lines]
> remember one method regardless of the type that he is passing in. Surely
> there must be some way around this?

No. The compiler needs to know about the classes represented by the
parameters to the methods.

Suppose you had this:

void Method (Foo x)
void Method (Bar y)

and the compiler knew about Foo, but not about Bar.

Now, if you tried to do Method(10) the compiler wouldn't know what to
do. It could look for a conversion from int to Foo, but it couldn't
look for a conversion from int to Bar because it wouldn't know what
type Bar was to start with.

Basically, any dependencies which are exposed in the API need to be
referenced by the client.

Signature

Jon Skeet - <skeet@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

Michael Brooks - 16 Mar 2006 18:07 GMT
> Now, if you tried to do Method(10) the compiler wouldn't know what to
> do. It could look for a conversion from int to Foo, but it couldn't
> look for a conversion from int to Bar because it wouldn't know what
> type Bar was to start with.
> Basically, any dependencies which are exposed in the API need to be
> referenced by the client.

Point taken Jon, but that involves an implicit cast, which muddies the
picture. I'm not doing that. To continue your analogy, I'm explicitly passing
in a Foo, but the compiler's still not up to the job. As I see it, this is a
fundamental problem with dotNet's principle of binding an assembly's metadata
into the assembly itself. In C/C++ we didn't do that - the metadata went in a
header file and the compiler only used that. Linkage was done by a linker
that only followed external references that were actually used. Hence the
equivalent in C++ (below) works fine.

// Library Class1.lib
#include "..\ClassA\ClassA.h"
#include "..\ClassB\ClassB.h"
class Class1
{
public:
    static void    setVar(ClassA    &reportVar);
    static void    setVar(ClassB    &reportVar);
};

// Application MyApp.exe
#include "..\Class1\Class1.h"
#include "..\ClassB\ClassB.h"
void main(void)
{
    ClassB        myVar;
    Class1::setVar(myVar);
}

I can link the above into a working application with a Class1.lib,
ClassB.lib but no ClassA.lib
It looks as though dotNet can't handle this.
Jon Skeet [C# MVP] - 16 Mar 2006 18:42 GMT
> > Now, if you tried to do Method(10) the compiler wouldn't know what to
> > do. It could look for a conversion from int to Foo, but it couldn't
[quoted text clipped - 5 lines]
> Point taken Jon, but that involves an implicit cast, which muddies the
> picture. I'm not doing that.

No, but how is the compiler meant to know that? Currently, it's a very
simple rule - if you expose something in your public API, the users of
that API need to know about that type. It sounds to me like you're
proposing something much more complicated - and that always makes me
very nervous.

> To continue your analogy, I'm explicitly passing in a Foo, but the
> compiler's still not up to the job. As I see it, this is a
> fundamental problem with dotNet's principle of binding an assembly's metadata
> into the assembly itself. In C/C++ we didn't do that - the metadata went in a
> header file and the compiler only used that.

Yes, and we've seen how easy it was to work with that, haven't we? ;)

> It looks as though dotNet can't handle this.

Indeed. And personally, I prefer the nice and simple model.

Signature

Jon Skeet - <skeet@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

Michael Brooks - 16 Mar 2006 19:08 GMT
> Currently, it's a very
> simple rule - if you expose something in your public API, the users of
> that API need to know about that type.

If that's the case, how come it all compiles OK when I change the names of
my overloaded methods to differing names? I'm still exposing the WebControl
in my API, but the compiler no longer seems to mind. That implies that there
is a level of intelligence in there more advanced than the simple rule that
you state above - it only gets confused when handling overloads. Any thoughts?
Jon Skeet [C# MVP] - 16 Mar 2006 23:38 GMT
> > Currently, it's a very
> > simple rule - if you expose something in your public API, the users of
[quoted text clipped - 5 lines]
> is a level of intelligence in there more advanced than the simple rule that
> you state above - it only gets confused when handling overloads. Any thoughts?

That surprises me, to be honest. I guess at that point the compiler
hasn't had to make *any* decisions at all about types that it doesn't
know about. It still doesn't seem unreasonable to me that the compiler
should complain when it's asked to make decisions involving types it
hasn't the faintest idea about.

Signature

Jon Skeet - <skeet@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

Michael Brooks - 16 Mar 2006 22:30 GMT
OK, so here's the solution. Instead of exposing multiple overloads, each of
which takes a parameter of a different type, expose just one method which
takes a parameter of type Object. Inside the method use reflection to
determine what type of object has been passed in and act accordingly.
Not just as tight as C++ would do it, but at least it will produce the
desired result.
My trouble is I still think like a C++ programmer    >oP
I'll get there some day...

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.