Another C# critique

  • Thread starter christopher diggins
  • Start date
A

Andreas Huber

Stu said:
I'd just like to butt-in on question 12, public fields. One of my
favourite C++ questions (with no right or wrong answer) is: "given
that we don't like public data fields, and given that the people who
implement STL libraries are pretty smart, why is pair<A, B> generally
implemented with two public data fields?"

Because the pair is a generic container for two values. The two data members
of the pair don't have anything to do with eachother (even if they had, the
clients of the pair wouldn't want/need know about it). There are no
preconditions, post conditions and invariants to enforce. Consequently,
there are no getter/setter accessors because that would not add anything.

Regards,

Andreas
 
A

Andreas Huber

codymanix said:
If you can state only one example where multiple nheritance is
required I'll believe you,
otherwise not. Multiple Inheritance is just bad style used by poor
programmers.
All Multiple Inheritance scenarios are best solved using composition
instead.

Please then tell me how to implement an indirect visitor in C++ without MI
(I'm sure google'll give you all you need to know).

Regards,

Andreas
 
A

Andreas Huber

codymanix said:
The whole const-stuff in C++ is stupid. Classes should be
self-contained, and therefore everybody should be able to modify them
safely. This is real-world,
or do you know objects in the real world that are constant? :)

Maybe in C++ it was neccesary due to the whole pointer-stuff and so
on but in other
languages it is not.

Oh, yet another ingenious insight!

http://www.research.att.com/~bs/blast.html

I'm afraid the "pointer-stuff" has not much to do with whether const makes
sense or not. It is also worth noting that there is an experimental C#
compiler supporting const (Rotor I think) and that most experts would rather
see const back in Java and C#. Reference types with value-type semantics
(e.g. string) would benefit from const (performance-wise).

Regards,

Andreas
 
A

Andreas Huber

codymanix wrote:
[snip]
Deterministic destructors are good for deallocating native resources
only. Theoretically
they could make dtors of value-types deterministic, but they don't. I
don't know why.

Boxing.

Regards,

Andreas
 
J

Jon Skeet [C# MVP]

codymanix said:
The whole const-stuff in C++ is stupid. Classes should be self-contained,
and therefore everybody should be able to modify them safely. This is
real-world, or do you know objects in the real world that are constant? :)

This really doesn't hold up at all.

For instance, it's handy to be able to return an array from a method,
some times - the array could fundamentally be part of the instance's
state. However, I want the contents of that array to be effectively
read-only, so that the caller can't tamper with the state of the class
just by using:

byte[] data = instance.StateData;
data[0] = 15;

Const-correctness would prevent that (and many similar problems, mostly
to do with collections).
 
M

Max Guernsey

I have questions for you. Please see below.



The whole const-stuff in C++ is stupid.



If const-correctness is stupid, does that make it stupid in all of its
forms? For example: are read-only properties and fields stupid? Are you
saying that C# should remove the partial implementation of
const-correctness-support that it already has?



Would support for const-correctness not benefit the class-system designer by
giving him (or her) a whole new degree of control over the users of his
classes? Doesn't const-correctness allow for faster code by removing the
need for unnecessary copies?


Classes should be self-contained,
and therefore everybody should be able to modify them safely. This is
real-world,
or do you know objects in the real world that are constant? :)



What real-world objects are "self-contained?"



If you are thinking of animals, what animal can be safely modified without
restriction?



Which computer programs or class-systems are perfect models of the real
world?



Aren't there objects that cannot be significantly modified by some other
objects? For instance: how could you or I significantly alter the shape of
our galaxy?

Maybe in C++ it was neccesary due to the whole pointer-stuff and so on but
in other
languages it is not.



You hurt my feelings when you refer to C++ in the past tense. It's going to
make a comeback. If C# 2.0 were going to allow for multiple inheritance one
could say it already has.



-- Max
 
G

Guest

C++ over time has become a language of kludges and fixes that the developer
has to code because the compiler is badly designed in the first place.
 
S

Stu Smith

And modern C++ compilers can generally inline small functions.

As Andreas said in the next post, it's because pair is one of those classes
that everything is know about; there is nothing to check, no unknown future
uses. In certain cases there are classes like that, and that's (one of the
reasons) why C# and C++ don't disallow public data members.

Why have several lines when two will do?


codymanix said:
Stu Smith said:
I'd just like to butt-in on question 12, public fields. One of my favourite
C++ questions (with no right or wrong answer) is: "given that we don't like
public data fields, and given that the people who implement STL libraries
are pretty smart, why is pair<A, B> generally implemented with two public
data fields?"

Uuuh...Performance? But wait! What was the Jit good for?
Yes, it can automatically inline calls to Properties. So what?

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
 
M

Max Guernsey

C++ over time has become a language of kludges and fixes that the developer
has to code because the compiler is badly designed in the first place.



Wow! I have never heard it stated quite so eloquently. I've been looking
for someone like you. I only have one question:



Where do I ship the time machine you're going to use to go back and make
sure that C++ was designed properly? Please make sure that it didn't have
templates so that we dinosaurs are lucky enough to have to sprinkle our code
with typecasts like you advanced C# programmers. Also, if you have time,
can you see to it that multiple-inheritance was replaced by interfaces so
that I can spend my life retyping the same method over and over?



Thanks in advance.
 
M

Matthew Watson

The whole const-stuff in C++ is stupid. Classes should be self-contained,
and therefore everybody should be able to modify them safely. This is
real-world,
or do you know objects in the real world that are constant? :)

I've missed the first part of this discussion, so forgive me if someone has
already said this:

One of the really useful reasons to be able to specify that a function does
not change one of its operands is for self-documentation.

In C++, if you see that a function argument is declared with a const-ref
operand, you need look no further to know that calling that function will
not change the operand. (I'm ignoring erroneous code which casts away the
const in the function - such code is buggy).

In C#, whenever I pass a reference-type to an unfamiliar function, I need to
consult the documentation and/or inspect the function's implementation in
order to determine whether the operand may be changed.

What's more, if I am the implementer of such a function, I can easily forget
and change the operand. If it could be const, then the compiler wouldn't
allow you to.

Now I realise that you can argue that you should always fully consult the
documentation for any function. But the lack of const can make you have to
search more of the code, particularly in the face of incomplete or possibly
out-of-date documentation. Even worse, the documentation may say that the
function doesn't change it's operand - and that may well have been true when
the documentation was written. Alas, a later maintenance programmer has
optimised the code in the function somewhat, and as a side-effect has
changed the operant. Blam! There's a bug that would instantly be caught if
you had constant operands.

As another example, suppose you were looking at some code that used a Matrix
class. You come across this function:

Matrix m1 = new Matrix( 4, 12 );
....
Matrix m2 = invert_matrix( m1 );

You consult the documentation and find that it says: "invert_matrix returns
the inverse of the specified matrix". And that's about it (about from some
info about possible exceptions and un-invertable matrices). Now, of course,
you have to go and inspect a load of complicated matrix-inversion code just
to see if the operand is changed.

You see, it's all about code clarity and self-documentation.
 
W

Willy Denoyette [MVP]

But what exactly did you hear?
Also note that assemblies cannot hold other assemblies, and assembly is the
unit of deployment that consists of one or more modules (NOT assemblies).
Why would you need to embed an assembly into another?
The only possibility to build multiple module assemblies now, is by using
the command-line build tools, the upcomming version of VS will add this
function to the IDE.
But again this has nothing in common with static linking.
Willy.
 
C

codymanix

What is it about my brain? I am having trouble expressing the whole
The whole const-stuff in C++ is stupid. Classes should be self-contained,
and therefore everybody should be able to modify them safely. This is
real-world, or do you know objects in the real world that are constant?
:)

This really doesn't hold up at all.

For instance, it's handy to be able to return an array from a method,
some times - the array could fundamentally be part of the instance's
state. However, I want the contents of that array to be effectively
read-only, so that the caller can't tamper with the state of the class
just by using:

byte[] data = instance.StateData;
data[0] = 15;

Const-correctness would prevent that (and many similar problems, mostly
to do with collections).


As I said, const correctness is only useful with not fully selfcontained
like pointers, arrays and so on.
in C# you would write an accessor method which supports only get to retrieve
the array's values:

int this[int index]
{
get {return a[index];}
}

Iam still waiting for the time where C# will support named indexers like in
VB.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu
[noncommercial and no ****ing ads]
 
C

cody

If you can state only one example where multiple nheritance is
Please then tell me how to implement an indirect visitor in C++ without MI
(I'm sure google'll give you all you need to know).

Iam not sure yet was the "indirect visitor" pattern is but iam sure it can
be better
solved using composition or interfaces.

It would be great if you could explain me a little about "indirect visitor".
 
C

cody

The whole const-stuff in C++ is stupid. Classes should be
Oh, yet another ingenious insight!

http://www.research.att.com/~bs/blast.html

I'm afraid the "pointer-stuff" has not much to do with whether const makes
sense or not. It is also worth noting that there is an experimental C#
compiler supporting const (Rotor I think) and that most experts would rather
see const back in Java and C#. Reference types with value-type semantics
(e.g. string) would benefit from const (performance-wise).


Why would they benefit from const? Are you talking about immutable classes
or immutable objects now?
 
C

cody

One of the really useful reasons to be able to specify that a function
does
not change one of its operands is for self-documentation.

Normally you don't have to care wheather an object is changed or not since
all objects
should be self-contained.
As another example, suppose you were looking at some code that used a Matrix
class. You come across this function:

Matrix m1 = new Matrix( 4, 12 );
...
Matrix m2 = invert_matrix( m1 );

You consult the documentation and find that it says: "invert_matrix returns
the inverse of the specified matrix". And that's about it (about from some
info about possible exceptions and un-invertable matrices). Now, of course,
you have to go and inspect a load of complicated matrix-inversion code just
to see if the operand is changed.


Such things like arrays, matrices, lists and so on are generic containers
which are not
really selfcontained since they represent no real-world object. You can
always use a wrapper or only provide an indexer/enumerator that doesn't
allow changes.

the problem with const correctness is if you change your mind and want that
a method is able to change the parameter, you have to change all const
specifiers in the whole library and all dependent apps!
 
B

Bret Pehrson

Cody -- wow, you must be incredible if you can make a statement such as:
Multiple Inheritance is just bad style used by poor programmers.

MI *IS NOT* bad style, it is a language construct. Style, for the rest of the
world, is *independent of constructs*. If it weren't, we wouldn't have:

recursion
switch statements
global scope/variables
break/continue
return (except at the end of a function/method)
etc.
etc.
etc.

Statements like yours are the *VERY REASON* that MI and other constructs are
frowned upon. Rather than denigrating language features, you should redirect
your energy to elucidating on style for the benefit of all programmers, poor or
otherwise.
*** NO MULTIPLE INHERITANCE ***!!!

Biggest fault of C# in my opinion.

If you can state only one example where multiple nheritance is required I'll
believe you,
otherwise not. Multiple Inheritance is just bad style used by poor
programmers.
All Multiple Inheritance scenarios are best solved using composition
instead.

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
 
M

Matthew W. Jackson

Yes, MI makes it easy to implement abstract visitors in C++.

However, we're talking about C#, and C# has delegates which replace many
uses of the Visitor pattern.

As for indirect visitor, which, if I understand correctly is just a specific
application of double-dispatch, I would guess that a collection of Delegates
pointing to virtual classes (simulating a double V-Table) would work.

I'd have to see a real example to come up with a solution though. I came
across a few other examples of uses, but I'm still looking for one that's
really elegant. A parser-generator might use one, but then again I think
delegates could be used. I haven't really been forced to thought about it.

Perhaps you could provide a link to a good, elegant use of Indirect
Visitors. I've already found
http://www.bleading-edge.com/Publications/C++Report/v9805/Column11.htm, but
is there a better example?

Because I'd love to try to figure out an alternative in C# that doesn't rely
on Multiple Inheritance. If nothing else I'd like to try for the challenge.

--Matthew W. Jackson
 
R

Rob Teixeira [MVP]

OK kids, with so many other things to argue about, let's not keep going with
the C++ vs. C# battle. They are two languages perfectly suited to different
types of programming. Neither is obsolete. C++ caters to the crowd and the
projects requiring maximum flexibility and power, at the cost of being
burdened with a large number of arcane syntactical and structural nuances
that the programmer must be aware of at all times. The language also favors
that power and flexibility at the cost of automatic
language/compiler-induced robustness and security. Looking at it from this
perspective, C# is the exact oposite. C# goes a long way to protecting
programmers from themselves, and boosts productivity at the cost of being
less flexible. However, clearly both are needed, and neither language is
going to die anytime soon. Hell, if COBOL is still around, just imagine how
long C++ will be ;-)

And while I think there are stricter controls over the evolution of C#, and
it didn't start from ground zero (like C++ coming from the C world, which
most claim to be the roots of some of C++'s worst nuances in an effort to
retain backwards compatibility), I do believe C# will develop it's own
quirks as time progresses. However, I would take a language that evolves to
meet new challenges and paradigms any day, even if that means living with a
few quirks, over one that is super clean yet completely stagnant - that is a
recipe for extinction and irrelevance.

-Rob Teixeira [MVP]
 
J

Jon Skeet [C# MVP]

cody said:
the problem with const correctness is if you change your mind and want that
a method is able to change the parameter, you have to change all const
specifiers in the whole library and all dependent apps!

No, that's the *good* thing about const correctness. Otherwise, all
that changes is the documentation (you do document whether or not
methods will change data within parameters, don't you?) and people may
well not notice. They may well be making an assumption that you're
*not* going to change things. At that stage, the code is broken, but
you don't know it. With const correctness, the compiler *tells* you
that the code is broken, and you can examine every invocation of the
method and see whether it's still okay or whether you need to create a
copy.
 
A

Andreas Huber

Matthew said:
Yes, MI makes it easy to implement abstract visitors in C++.

However, we're talking about C#, and C# has delegates which replace
many uses of the Visitor pattern.

As for indirect visitor, which, if I understand correctly is just a
specific application of double-dispatch, I would guess that a
collection of Delegates pointing to virtual classes (simulating a
double V-Table) would work.

Sorry, I meant "acyclic visitor". Here's a good article:

http://www.objectmentor.com/resources/articles/acv.pdf

Regards,

Andreas
 

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

Similar Threads

CSharp Coding Standards 18

Top