Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Borland C# Builder vs VS.NET

1 view
Skip to first unread message

tecnova

unread,
Aug 28, 2003, 8:13:44 PM8/28/03
to
I just got C# Builder and was surprised that the component One Enterprise
Suite with serial number was included in the package free of charge or as
pasrt of the package. Also installation af all of it including the .net
frame work took less that 10 minutes as oppsoed to the VS long time. The IDE
is definately nice.


"Monica Tarquini" <monicaa...@antispam.com> wrote in message
news:XDGwa.2942$Ny5....@twister2.libero.it...
> What do you think about Borland C# Builder?
> I don't know what should I buy between Borland C# Builder and VS.NET.
> Any suggests? Do you know the differences?
> Thanks.
>
> Kisses,
> Monica
>
>


Miha Markic

unread,
Aug 29, 2003, 5:24:29 AM8/29/03
to
Geee, you serius?

"tecnova" <tecn...@charter.net> wrote in message
news:vkt6mj1...@corp.supernews.com...


> I just got C# Builder and was surprised that the component One Enterprise
> Suite with serial number was included in the package free of charge or as
> pasrt of the package.

Ehmm. Isn't C#B a bit more pricey than VS.NET?
You think that COE price isn't included in the C#B price. Khmm khmm.

Also installation af all of it including the .net
> frame work took less that 10 minutes as oppsoed to the VS long time.

You need to install it only one time ....

The IDE
> is definately nice.

Wait till you start using it.
Just try creating a macro ;-)

Miha


Magnus Lidbom

unread,
Aug 29, 2003, 5:27:39 AM8/29/03
to

"Jon Skeet" <sk...@pobox.com> wrote in message
news:MPG.1937e3ef2...@news.microsoft.com...
> Marc Scheuner [AD MVP] <m.sch...@inova.SPAMBEGONE.ch> wrote:
> > >2. The compiler IS NOT OF BORLAND!.
> >
> > Well - to some degree. As I understand it, the "compiler" that
> > converts C# code into MSIL *IS* from Borland - or at least was
> > extended / tweaked by Borland.
>
> It'll be interesting to see whether it contains the same
> overload/override bug that csc does (and which the Mono compiler
> emulates)...
I've missed that. Got a link, or time to explain?

/Magnus Lidbom

<snip>


Jon Skeet

unread,
Aug 29, 2003, 5:47:31 AM8/29/03
to
Magnus Lidbom <magnus...@hotmail.com> wrote:
> > It'll be interesting to see whether it contains the same
> > overload/override bug that csc does (and which the Mono compiler
> > emulates)...

> I've missed that. Got a link, or time to explain?

Sure. There are two types of bug, one of which Mono emulates and one of
which it doesn't. There's just a chance that one of them actually
*isn't* a bug, and is just the specification being pretty tricky to
read - and quite bizarre as well.

Here's the one which isn't emulated by Mono, and is thoroughly weird:

using System;

public class Base
{
public virtual void Method (int parameter)
{
Console.WriteLine ("int");
}
}

public class Derived : Base
{
public void Method (double parameter)
{
Console.WriteLine ("double");
}

public override void Method (int parameter)
{
Console.WriteLine ("int");
}

public static void Main()
{
Derived d = new Derived();
d.Method(5);
}
}

The above prints "double" when compiled with csc, and I don't really
see why it should.

--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too

Magnus Lidbom

unread,
Aug 29, 2003, 7:33:15 AM8/29/03
to

"Jon Skeet" <sk...@pobox.com> wrote in message
news:MPG.19b93184c...@news.microsoft.com...

> Magnus Lidbom <magnus...@hotmail.com> wrote:
> > > It'll be interesting to see whether it contains the same
> > > overload/override bug that csc does (and which the Mono compiler
> > > emulates)...
>
> > I've missed that. Got a link, or time to explain?
>
> Sure. There are two types of bug, one of which Mono emulates and one of
> which it doesn't. There's just a chance that one of them actually
> *isn't* a bug, and is just the specification being pretty tricky to
> read - and quite bizarre as well.
>
> Here's the one which isn't emulated by Mono, and is thoroughly weird:
>
> using System;
>
> public class Base
> {
> public virtual void Method (int parameter)
> {
> Console.WriteLine ("int");
> }
> }
>
> public class Derived : Base
> {
> public void Method (double parameter)
> {
> Console.WriteLine ("double");
> }
>
> public override void Method (int parameter)
> {
> Console.WriteLine ("int");
> }
>
> public static void Main()
> {
> Derived d = new Derived();
> d.Method(5);
> }
> }
>
> The above prints "double" when compiled with csc, and I don't really
> see why it should.
That's a really nasty bug, and it's still there in VS2003. Any MS employee
with information on the status of this bug out there?

I took a quick stab at googling for the other potential bug, but couldn't find
it, anyone have more information on that?

/Magnus Lidbom

Jon Skeet

unread,
Aug 29, 2003, 8:31:41 AM8/29/03
to
Magnus Lidbom <magnus...@hotmail.com> wrote:
> > The above prints "double" when compiled with csc, and I don't really
> > see why it should.

> That's a really nasty bug, and it's still there in VS2003. Any MS employee
> with information on the status of this bug out there?
>
> I took a quick stab at googling for the other potential bug, but couldn't find
> it, anyone have more information on that?

The other potential bug was very very similar:

using System;

public class Base
{
public void Method (int parameter)
{
Console.WriteLine ("int");
}
}

public class Derived : Base
{
public void Method (double parameter)
{
Console.WriteLine ("double");
}

public static void Main()
{
Derived d = new Derived();
d.Method(5);
}
}

Actual Results:
double

Expected Results:
int

However, the spec (fairly obscurely) says that because there's *a*
method in the derived class which is applicable, *all* methods in the
base class should be ignored.

Pete

unread,
Aug 29, 2003, 10:41:31 AM8/29/03
to
Hi,

Jon Skeet wrote:
> The above prints "double" when compiled with csc, and I don't really
> see why it should.

In C++ it would work a similar way (a method with same name in derived class
hides the inherited method -- even with different signatures), see here:

http://www.research.att.com/~bs/bs_faq2.html#overloadderived

That appears to be the same as your second example. The first is probably a
similiar effect (and for similar reasons). I doubt very much that it is a
bug (although you'd think a compiler warning would be in order).

Pete


Jon Skeet

unread,
Aug 29, 2003, 3:20:09 PM8/29/03
to

No - although you're right about C++'s behaviour with the second of my
examples (which isn't a bug, I agree, although I still find it odd -
Java defines it to be ambiguous and gives an error, IIRC), it behaves
as I'd expect it to with the first example. Here's the C++ code
(adapted from the above page):

#include<iostream>
using namespace std;

class B {
public:
virtual int f(int i) { cout << "f(int): "; return i+1; }
// ...
};

class D : public B {
public:
double f(double d) { cout << "f(double): "; return d+1.3; }
int f(int i) { cout << "overridden(int): "; return i+1; }
// ...
};

int main()
{
D* pd = new D;

cout << pd->f(2) << '\n';
cout << pd->f(2.3) << '\n';
return 0;
}

The output is:
overridden(int): 3
f(double): 3.6


Why *wouldn't* it give the above output? It's got the choice of two
methods both defined in the same class, one of which is requires no
conversion - why on earth would it choose the version which needs a
conversion, just because it happens to be overriding a method in the
base class?

The bit of specification which explains the case which is odd but not a
bug *doesn't* cover this case - I really think it is a bug.

Pete

unread,
Aug 29, 2003, 4:47:25 PM8/29/03
to
Hi,

Jon Skeet wrote:
> Why *wouldn't* it give the above output? It's got the choice of two
> methods both defined in the same class, one of which is requires no
> conversion - why on earth would it choose the version which needs a
> conversion, just because it happens to be overriding a method in the
> base class?
>
> The bit of specification which explains the case which is odd but not
> a bug *doesn't* cover this case - I really think it is a bug.

Surely it's just a case of c# picking the non-virtual method first? I.e. it
finds the non-virtual method that fits the bill and just uses it (without
checking for an exact match in the virtuals)?

Arguably this could be a bug (feature? ;) ). Maybe a few more test cases
would verify what exact conditions this occurs under?

I'm just too lazy to bother with it myself. :)

Pete


Jon Skeet

unread,
Aug 29, 2003, 4:55:41 PM8/29/03
to
Pete <pvi...@gawab.com> wrote:
> > The bit of specification which explains the case which is odd but not
> > a bug *doesn't* cover this case - I really think it is a bug.
>
> Surely it's just a case of c# picking the non-virtual method first? I.e. it
> finds the non-virtual method that fits the bill and just uses it (without
> checking for an exact match in the virtuals)?

But that's not how C# is specified, and it would be a very screwed up
specification.



> Arguably this could be a bug (feature? ;) )

I really don't think it's arguable - unless someone shows me a bit of
the spec which explains it away, I'll keep believing it really is just

Mike Schilling

unread,
Aug 29, 2003, 7:23:11 PM8/29/03
to

"Jon Skeet" <sk...@pobox.com> wrote in message
news:MPG.19b958071...@news.microsoft.com...

C++ would guve the same result, because any Derived::Method() hides all
Base::Method()s.

Java would call this ambiguous. Its rule is that, to avoid ambiguity, there
must be one method which is most specific both in parameters and defining
class. Since Derived is more specific than Base but double is less specific
than int, there is no most specific method.


Jon Skeet

unread,
Aug 30, 2003, 2:23:20 AM8/30/03
to
Mike Schilling <mscotts...@hotmail.com> wrote:
> C++ would guve the same result, because any Derived::Method() hides all
> Base::Method()s.

Yup.



> Java would call this ambiguous. Its rule is that, to avoid ambiguity, there
> must be one method which is most specific both in parameters and defining
> class. Since Derived is more specific than Base but double is less specific
> than int, there is no most specific method.

And again, yup. I prefer this approach, myself.

Mike Schilling

unread,
Aug 30, 2003, 3:22:07 AM8/30/03
to

"Jon Skeet" <sk...@pobox.com> wrote in message
news:MPG.19b93184c...@news.microsoft.com...

> Magnus Lidbom <magnus...@hotmail.com> wrote:
> > > It'll be interesting to see whether it contains the same
> > > overload/override bug that csc does (and which the Mono compiler
> > > emulates)...
>
> > I've missed that. Got a link, or time to explain?
>
> Sure. There are two types of bug, one of which Mono emulates and one of
> which it doesn't. There's just a chance that one of them actually
> *isn't* a bug, and is just the specification being pretty tricky to
> read - and quite bizarre as well.
>
> Here's the one which isn't emulated by Mono, and is thoroughly weird:
>
> using System;
>
> public class Base
> {
> public virtual void Method (int parameter)
> {
> Console.WriteLine ("int");
> }
> }
>
> public class Derived : Base
> {
> public void Method (double parameter)
> {
> Console.WriteLine ("double");
> }
>
> public override void Method (int parameter)
> {
> Console.WriteLine ("int");
> }
>
> public static void Main()
> {
> Derived d = new Derived();
> d.Method(5);
> }
> }
>
> The above prints "double" when compiled with csc, and I don't really
> see why it should.

Horrifyingly, this *is* what the language definition says to do.

According to 7.5.5.1:

The set of candidate methods for the method invocation is constructed.
Starting with the set of methods associated with M, which were found by a
previous member lookup (§7.3), the set is reduced to those methods that are
applicable with respect to the argument list A.

7.3 says:

A member lookup of a name N in a type T is processed as follows:
· First, the set of all accessible (§3.5) members named N declared
in T and the base types (§7.3.1) of T is constructed. Declarations that
include an override modifier are excluded from the set. If no members named
N exist and are accessible, then the lookup produces no match, and the
following steps are not evaluated.

That is, Derived::Method(int) is removed from consideration because it's an
override (by 7.3). Now Derived::Method(double) is chosen, since it's the
only overload of Derived::Method remaining. Q.E.D.

Once you remove overloads from consideration, you've lost the information
about what classes really declare a method with that signature; all that's
left is what classes *introduced* that signature, so applying the rule in
7.5.5.1 that prefers types lower in the inheritance tree leads to
nonsensical results, as your example demonstrates. This looks to me like a
complete botch, as if no one thought through the consequences of combining
7.3 and 7.5.5.1.

Would anyone from Microsoft care to address this?


Jon Skeet

unread,
Aug 30, 2003, 4:40:20 AM8/30/03
to
Mike Schilling <mscotts...@hotmail.com> wrote:
> > The above prints "double" when compiled with csc, and I don't really
> > see why it should.
>
> Horrifyingly, this *is* what the language definition says to do.

<snip>

Hmm... I don't remember seeing the override bit before, but you're
right.

It's very, very odd, because following that, surely overriding methods
would *never, ever* get called. In the simple case without the
overloading, the base method would be chosen every time - which means
the compiler is broken (according to the spec) in millions of simpler
cases. (Let me know if you don't see what I mean, and I'll give an
example.)

I don't know what the point of that clause (removing declarations that
include an override modifier) is meant to be, to be honest - but it
looks to me like the spec is completely, fundamentally broken at the
moment.

I suspect that fixing it for the simple case would also fix it for this
"bug" case as well, so that the more-applicable int method would be
called here.

> Would anyone from Microsoft care to address this?

Yes, I'd be interested to hear from them about it too :)

Richard Cook

unread,
Aug 30, 2003, 5:31:29 AM8/30/03
to
just ran this in c# builder:

class Base1
{
public virtual void DoSomething(string s)
{
Console.WriteLine("Base1::DoSomething(string s={0})", s);
}
static void Main(string[] args)
{
Sub1 s = new Sub1();
s.DoSomething("Call sub with string");
Console.WriteLine();
Base1 b = new Sub1();
b.DoSomething("Call base with string");
Console.ReadLine();
}
}
class Sub1 : Base1
{
public override void DoSomething(string s)
{
base.DoSomething(s);
Console.WriteLine("Sub1::DoSomething(string s={0})", s);
}
public void DoSomething(object o)
{
Console.WriteLine("Sub1::DoSomething(object o={0})", o);
}
}

prints

Sub1::DoSomething(object o=Call sub with string)

Base1::DoSomething(string s=Call base with string)
Sub1::DoSomething(string s=Call base with string)

so I guess it also exhibits this behaviour.

"Jon Skeet" <sk...@pobox.com> wrote in message

news:MPG.19ba734ff...@news.microsoft.com...

Jon Skeet

unread,
Aug 30, 2003, 6:30:18 AM8/30/03
to
Richard Cook <rp...@msn.com> wrote:
> just ran this in c# builder:

<snip>

> prints
>
> Sub1::DoSomething(object o=Call sub with string)
>
> Base1::DoSomething(string s=Call base with string)
> Sub1::DoSomething(string s=Call base with string)
>
> so I guess it also exhibits this behaviour.

Yup... interesting...

Pete

unread,
Aug 30, 2003, 11:10:29 AM8/30/03
to
Hi,

Richard Cook wrote:
> so I guess it also exhibits this behaviour.

Isn't it the same compiler? Given that the compilers are part of the
framework and all?

Pete


Mike Schilling

unread,
Aug 30, 2003, 12:22:33 PM8/30/03
to

"Jon Skeet" <sk...@pobox.com> wrote in message
news:MPG.19ba734ff...@news.microsoft.com...

> Mike Schilling <mscotts...@hotmail.com> wrote:
> > > The above prints "double" when compiled with csc, and I don't really
> > > see why it should.
> >
> > Horrifyingly, this *is* what the language definition says to do.
>
> <snip>
>
> Hmm... I don't remember seeing the override bit before, but you're
> right.
>
> It's very, very odd, because following that, surely overriding methods
> would *never, ever* get called. In the simple case without the
> overloading, the base method would be chosen every time - which means
> the compiler is broken (according to the spec) in millions of simpler
> cases. (Let me know if you don't see what I mean, and I'll give an
> example.)

If I understand what you're saying, I disagree :-)

These are the rules for compile-time processing, that is, choosing a method
signature to call. Run-time dispatch of virtual functions will still result
in calling the appropriate override with that signature.

That is, in the slightly more complex example:

using System;

public class Base {
public virtual void Method (int parameter) {

Console.WriteLine ("Base::int");
}
}

public class Derived : Base {
public virtual void Method (double parameter) {
Console.WriteLine ("Derived::double");
}

public override void Method (int parameter) {

Console.WriteLine ("Derived::int");
}

}

public class MoreDerived : Derived {
public override void Method (double parameter) {
Console.WriteLine ("MoreDerived::double");
}

public override void Method (int parameter) {

Console.WriteLine ("MoreDerived::int");
}

public static void Main() {
MoreDerived d = new MoreDerived();
d.Method(5);
}
}

At compile-time, Derived::Method(double) is chosen, as the nearest
non-override method. At run-time, this dispatches to
MoreDerived::Method(double). This is still unfortunate, since that's the
wrong signature, but the botch happens at compile-time, not run-time.

>
> I don't know what the point of that clause (removing declarations that
> include an override modifier) is meant to be, to be honest - but it
> looks to me like the spec is completely, fundamentally broken at the
> moment.

I can see that clause (7.3) as a way of simplifying the discussion of the
algorithm for choosing a signature, by ensuring that the set of candidate
methods is unique with respect to signatures. It's only when you combine it
with 7.5.5.1 that the problems start. (If you change 7.3 to say
"Declarations *that are overridden* are excluded from the set", the problems
go away. The signatures are still unique, and now the candidate methods are
declared by the proper classes.)

I do agree with you about "completely and fundamentally broken". Even the
documentation for the .NET class library is affected. For instance,
consider System.IO.TextWriter.Write(int) vi
System.IO.TextWriter.Write(double); which will be called from
System.Console.Out(5)? I can't conclude Write(int) without looking at the
superclasses and determining where each overload was introduced. To be
useful under the current rules, class documentation needs to indicate which
methods are overrides and which superclass introduces them.

Jon Skeet

unread,
Aug 30, 2003, 12:32:21 PM8/30/03
to
Mike Schilling <mscotts...@hotmail.com> wrote:
> If I understand what you're saying, I disagree :-)

So do I now :) (Goodness knows what I was thinking about earlier on.)

<snip>



> > I don't know what the point of that clause (removing declarations that
> > include an override modifier) is meant to be, to be honest - but it
> > looks to me like the spec is completely, fundamentally broken at the
> > moment.
>
> I can see that clause (7.3) as a way of simplifying the discussion of the
> algorithm for choosing a signature, by ensuring that the set of candidate
> methods is unique with respect to signatures.

Right. It's unnecessary, given that a slightly later clause which says
that if a method in a derived class is in the set, all methods from the
base class are excluded, but there we go.

> It's only when you combine it
> with 7.5.5.1 that the problems start. (If you change 7.3 to say
> "Declarations *that are overridden* are excluded from the set", the problems
> go away.

Yes.

> The signatures are still unique, and now the candidate methods are
> declared by the proper classes.)

Yup.



> I do agree with you about "completely and fundamentally broken". Even the
> documentation for the .NET class library is affected. For instance,
> consider System.IO.TextWriter.Write(int) vi
> System.IO.TextWriter.Write(double); which will be called from
> System.Console.Out(5)? I can't conclude Write(int) without looking at the
> superclasses and determining where each overload was introduced. To be
> useful under the current rules, class documentation needs to indicate which
> methods are overrides and which superclass introduces them.

Yes - very strange indeed. If we're really, really lucky, this will be
fixed by C# v2 - but then it *is* actually a breaking change, so anyone
absolutely relying on it would be affected, which is a pain :(

Pete

unread,
Aug 30, 2003, 3:28:32 PM8/30/03
to
Hi,

Jon Skeet wrote:
> The above prints "double" when compiled with csc, and I don't really
> see why it should.

I used a converter to switch it to VB.NET and got this compiler message:


error BC31409: sub 'Method' must be declared 'Overloads' because another
'Method' is declared 'Overloads'.

Public Sub Method(ByVal parameter As Double)
~~~~~~

warning BC40003: sub 'Method' shadows an overloadable member declared in the
base class 'Base'. If you want to overload the base method, this method
must be declared 'Overloads'.

Public Sub Method(ByVal parameter As Double)
~~~~~~

Interesting, no?

Pete


Mike Schilling

unread,
Aug 30, 2003, 6:58:18 PM8/30/03
to

"Jon Skeet" <sk...@pobox.com> wrote in message
news:MPG.19bae1ec3...@news.microsoft.com...

> > I do agree with you about "completely and fundamentally broken". Even
the
> > documentation for the .NET class library is affected. For instance,
> > consider System.IO.TextWriter.Write(int) vi
> > System.IO.TextWriter.Write(double); which will be called from
> > System.Console.Out(5)? I can't conclude Write(int) without looking at
the
> > superclasses and determining where each overload was introduced. To be
> > useful under the current rules, class documentation needs to indicate
which
> > methods are overrides and which superclass introduces them.
>
> Yes - very strange indeed. If we're really, really lucky, this will be
> fixed by C# v2 - but then it *is* actually a breaking change, so anyone
> absolutely relying on it would be affected, which is a pain :(

Microsoft could do the following:

1. Announce that the spec is indeed broken, and provide the language they
intend to replace it with (for careful consideration and review.)
2. Provide a patch to the 1.1 compiler that issues a warning (and, by user
option, an error) when code which will acts incompatibly between versions is
compiled. (This warning/error should be emitted both for methods which will
cause the incompatibility when called and for the incompatible calls
themselves.)
3. Have the 2.x compilers also produce warnings for "possible
incompatibility with previous versions of the language."

Pete

unread,
Aug 30, 2003, 8:46:29 PM8/30/03
to
Hi,

Mike Schilling wrote:
> Microsoft could do the following:

We are, of course, assuming they know about it?

So far as I can see, none of them have replied to this thread. How likely is
it that a Microsoft employee would take the time to read a thread that
started with "Borland C# Builder vs VS.NET"?

Where did this stuff come from -- I'm just curious to know if M'Soft are
aware of it yet.

Pete


Mike Schilling

unread,
Aug 30, 2003, 8:58:52 PM8/30/03
to

"Pete" <pvi...@gawab.com> wrote in message
news:Pzb4b.1150$Ic6.5...@newsfep2-gui.server.ntli.net...

> Hi,
>
> Mike Schilling wrote:
> > Microsoft could do the following:
>
> We are, of course, assuming they know about it?
>
> So far as I can see, none of them have replied to this thread. How likely
is
> it that a Microsoft employee would take the time to read a thread that
> started with "Borland C# Builder vs VS.NET"?

That's why I changed the name. "Nonsensical overloading rules in C#" might
pique someone's curiosity. :-) Also, this began on the Friday night before
a holiday weekend. Many of them might have lives. Let's see what Tuesday
brings.

>
> Where did this stuff come from -- I'm just curious to know if M'Soft are
> aware of it yet.

Dunno. If necessary, I'll try to pursue it through what contacts I have.


Mike Schilling

unread,
Aug 30, 2003, 8:59:49 PM8/30/03
to

"Jon Skeet" <sk...@pobox.com> wrote in message
news:MPG.19b9ce268...@news.microsoft.com...

> Pete <pvi...@gawab.com> wrote:
> > > The bit of specification which explains the case which is odd but not
> > > a bug *doesn't* cover this case - I really think it is a bug.
> >
> > Surely it's just a case of c# picking the non-virtual method first? I.e.
it
> > finds the non-virtual method that fits the bill and just uses it
(without
> > checking for an exact match in the virtuals)?
>
> But that's not how C# is specified, and it would be a very screwed up
> specification.

Pete was very close to the right answer, and yes, it is.


Pete

unread,
Aug 31, 2003, 9:20:16 AM8/31/03
to
Hi,

Mike Schilling wrote:
> Pete was very close to the right answer, and yes, it is.

Woohoo!

That would be a first, then ;)

Pete


0 new messages