Another C# critique

  • Thread starter christopher diggins
  • Start date
A

Andreas Huber

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

In C#, reference types with value semantics (string, delegates, etc.) are
all immutable, i.e. when you call a function that "looks like a modifier" on
an object of these classes you will never modify the object itself. Instead
the original object is copied, the copy modfied and then returned. This is
because it would be very surprising if functions could modify such an object
that was passed as in parameter. This can lead to excessive copying and
that's also why there is the StringBuilder class. Another way of enforcing
constness is through read-only wrappers around collections. Note that this
means having another indirection between you and the data.
In C++ the very signature of a function will tell you whether it will be
modifying the passed arguments or not. Hence, immutable objects and
excessive copying are much less widespread and there is no need for runtime
read-only wrappers. Everything regarding constness is enforced at
compile-time.

Regards,

Andreas
 
A

Andreas Huber

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.

Would you please do all of us a favor and do some research before you make
such blanket statements? It is always easy to say something is badly
designed without saying why exactly you think so. The C++ committee is
certainly a bunch of smart, hard-working people. There *is* a reason behind
all the things you critisize as badly designed.
 
A

Andreas Huber

.. said:
Comparing C++ (unmanged) to C# is like apples to oranges, both are
fruits but very very different.

However if you comprae C++/CLI to C# then I will listen. Both are in
the same world, managed.

What the heck has that to do with const correctness (there is an
experimental C# compiler that supports const)?

Regards,

Andreas
 
G

Guest

Comparing C++ (unmanged) to C# is like apples to oranges, both are fruits
but very very different.

However if you comprae C++/CLI to C# then I will listen. Both are in the
same world, managed.

Andreas Huber said:
[snip]
Why would they benefit from const? Are you talking about immutable
classes or immutable objects now?

In C#, reference types with value semantics (string, delegates, etc.) are
all immutable, i.e. when you call a function that "looks like a modifier" on
an object of these classes you will never modify the object itself. Instead
the original object is copied, the copy modfied and then returned. This is
because it would be very surprising if functions could modify such an object
that was passed as in parameter. This can lead to excessive copying and
that's also why there is the StringBuilder class. Another way of enforcing
constness is through read-only wrappers around collections. Note that this
means having another indirection between you and the data.
In C++ the very signature of a function will tell you whether it will be
modifying the passed arguments or not. Hence, immutable objects and
excessive copying are much less widespread and there is no need for runtime
read-only wrappers. Everything regarding constness is enforced at
compile-time.

Regards,

Andreas
 
S

Sami Vaaraniemi

Andreas Huber said:
cody wrote: [snip]
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".

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

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

The base classes in acyclic visitor are abstract (no implementation), and
therefore, they can be expressed as interfaces. While C# does not support
multiple inheritance of classes, it does support multiple inheritance of
interfaces which makes implementing acyclic visitor in C# trivial (see
below).

That said, there are probably legitimate uses of MI where base classes have
implementation, too. In this case you could use composition or delegates to
get similar functionality.

using System;

namespace AcyclicModemVisitor
{
// IVisitor is a degenerate base interface for all visitors.
public interface IVisitor
{
}

// We could make this into an interface, too.
public abstract class Modem
{
public abstract void Accept(IVisitor visitor);
}

public interface IHayesModemVisitor
{
void Visit(HayesModem hm);
}

public class HayesModem : Modem
{
public override void Accept(IVisitor visitor)
{
IHayesModemVisitor hv = visitor as IHayesModemVisitor;
if (hv != null)
{
hv.Visit(this);
}
else
{
Console.WriteLine("*** ERROR: {0} cannot visit HayesModem",
visitor.ToString());
}
}
}

public interface IZoomModemVisitor
{
void Visit(ZoomModem zm);
}

public class ZoomModem : Modem
{
public override void Accept(IVisitor visitor)
{
IZoomModemVisitor zv = visitor as IZoomModemVisitor;
if (zv != null)
{
zv.Visit(this);
}
else
{
Console.WriteLine("*** ERROR: {0} cannot visit ZoomModem",
visitor.ToString());
}
}
}

//-------------------------
// ConfigureForDOSVisitor
//
// This visitor configures both Hayes and Zoom modems
// for DOS.
//
public class ConfigureForDOSVisitor : IVisitor, IHayesModemVisitor,
IZoomModemVisitor
{
public void Visit(HayesModem hm)
{
Console.WriteLine("ConfigureForDOSVisitor visiting {0}", hm);
}

public void Visit(ZoomModem zm)
{
Console.WriteLine("ConfigureForDOSVisitor visiting {0}", zm);
}
}

//--------------------------
// ConfigureForUnixVisitor
//
// This visitor configures only Zoom modems for Unix
//
public class ConfigureForUnixVisitor : IVisitor, IZoomModemVisitor
{
public void Visit(ZoomModem zm)
{
Console.WriteLine("ConfigureForUnixVisitor visiting {0}", zm);
}
}


class MainClass
{
[STAThread]
static void Main(string[] args)
{
// Create a bunch of modems to visit -
// in DOS, we have both Zoom and Hays modems
Modem[] dosModems = new Modem[] {
new ZoomModem(),
new HayesModem(),
new ZoomModem(),
new HayesModem()
};

// In Unix, we have only Zoom modems
Modem[] unixModems = new Modem[] {
new ZoomModem(),
new ZoomModem()
};

Console.WriteLine("Visiting DOS modems...");
ConfigureForDOSVisitor dosVisitor = new
ConfigureForDOSVisitor();
foreach (Modem modem in dosModems)
{
modem.Accept(dosVisitor);
}

Console.WriteLine("\nVisiting Unix modems...");
ConfigureForUnixVisitor unixVisitor = new
ConfigureForUnixVisitor();
foreach (Modem modem in unixModems)
{
modem.Accept(unixVisitor);
}

Console.WriteLine("\nTrying to visit DOS modems with Unix
visitor...");
foreach (Modem modem in dosModems)
{
modem.Accept(unixVisitor);
}
}
}
}
 
C

cody

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.

You aren't serious? Where is C# less flexible than C++? The ability to
change public
fields into Properties at any time is a good thing which isn't possible in
C++.
In C++ you have to rethink lots of things when you are attempting to change
a line of
code since you can introduce a lot of suble bug the compiler cannot catch
for you.
When you think Flexibility=="I can do every stupid thing I want, the
compiler won't hinder me" then yes, C++ is more 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 ;-)


I don't doubt this. C and C++ will be still popular in 10 years and still
used in 30 years.
 
C

cody

the problem with const correctness is if you change your mind and want
that
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.

Assumed I have a class Called DB_Connection. Further assumed I have
a method Read() in it. Knowing that a Read() doesn't alter the connection
itself I make the method const. Every clint that uses my class gets a "const
DB_Connection"
passed since they don't need to change the object.

Now I have the idea to increment a counter in the connection each time the
Read() method is used. Now what? I have to remove const from the Read()
method.
Additionally I have to remove const from every variable/parameter which
passes a "const DB_Connection". Stupid, isn't it.

Nobody should care about wheather an object is altered since you can always
safely alter a self-contained object. Additionally this encourages
programmed to make their objects more selfcontained and safe.

The only problem still are not fully selfcontained generic containers like
pointers arrays and lists. You can use a readonly wrapper here, an
enumerator or an readonly indexer.
 
R

Ravichandran J.V.

Attributes
[Transaction"AutoComplete"]

cuts out so many transaction management steps.

unsafe

when the going gets too experimental, unsafe is the way out because it
is usually the experimental who really holler over techniques (they
possess or have borrowed is of course a different issue) that are not
supported by technology.

Microsoft(?!)
I wouldn't talk too much if I were you about a company which can really
buy the mud out of everywhere just to get to know the critique and its
supporters!

The rest of course have been tackled better by others.

with regards,


J.V.Ravichandran
- http://www.geocities.com/
jvravichandran
- http://www.411asp.net/func/search?
qry=Ravichandran+J.V.&cob=aspnetpro
- http://www.southasianoutlook.com
- http://www.MSDNAA.Net
- http://www.csharphelp.com
- http://www.poetry.com/Publications/
display.asp?ID=P3966388&BN=999&PN=2
- Or, just search on "J.V.Ravichandran"
at http://www.Google.com
 
M

Matthew Watson

Normally you don't have to care wheather an object is changed or not since
all objects should be self-contained

Of course you must care! Whether an object is changed or not is crucially
important - the fact that an object is self-contained is completely
non-sequitor! You appear not to really understand the issues.
 
R

Roy Fine

Cody -- see inline

cody said:
You aren't serious? Where is C# less flexible than C++? The ability to
change public
fields into Properties at any time is a good thing which isn't possible in
C++.

That's not at all true. The __declspec(property) has been around for some
time... By many novice VC++ programmers, it is often overlooked as just a
COM extension (and in fact, the documentation leads one in that conclusion),
but it's there and it works well (albeit not a particularly portable
construct)... For the programmer that implements it, it is rather tedious -
but for the consumer/client of the class, it is just as efficient and
cosmetically appealing as class properties in other implementations.

Consider this rather absurd hack:

/* *********************************************** */
class SomethingWithProps{
public:
__declspec(property(get=get_HiddenValue,put=put_HiddenValue))
int PropValue; // not the real value, just a crutch for the declspec
private:
int realValue; // yep - this is the real property value
SomethingWithProps(){
PropValue=0;
}
public:
int get_HiddenValue(){return realValue;}
void put_HiddenValue(int val){realValue=val;}
static SomethingWithProps* Create(){
return new SomethingWithProps();
}
};
/* *********************************************** */
int _tmain(){
Console::WriteLine(S"Hello World");
SomethingWithProps *a = SomethingWithProps::Create();
a->PropValue = 100; // doing a property in VC++
printf("This is the value from property: %d",a->PropValue);
return 0;
}
In C++ you have to rethink lots of things when you are attempting to change
a line of
code since you can introduce a lot of suble bug the compiler cannot catch
for you.

That's not true for the general case (and consider subtle versus suble).
The probability of introducing a bug when changing a line of code is vastly
more dependent upon the level of expertise of the programmer (and the
general degree of attention being offered by the programmer) making the
change.

Novice VB/C# programmers can write pretty sophisticated apps. Novice C++
programmers get in a heap of trouble. Expert VC, Expert C#, and Expert VC++
programmers are, for all intents and purposes, equally good at 99.9% of the
apps. The problem is that great time lag between expert level amongst the
languages cited.
When you think Flexibility=="I can do every stupid thing I want, the
compiler won't hinder me" then yes, C++ is more flexible.


That is a child-like, absurd interpretation of Flexibility. Please
reconsider.

I don't doubt this. C and C++ will be still popular in 10 years and still
used in 30 years.

I don't want to pile on here - but computing will likely change so
dramatically in the next 5 years, that what happens in 10 years will hardly
be recognized as computing by those that are doing it now...


regards
roy fine

--
cody

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

cody

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?

There should be constant fields and constant(immutable) classes, but not
constant objects.
You cannot change someones eye-color. This applies to ALL human, so it would
be stupid to say:
you can change the hair color of this human but not the haircolor of that
human.
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?

making a class immutable makes copies also avoids copiing and allows faster
code,
without having the disadvantages of c++ const correctness.
What real-world objects are "self-contained?"

ALL real world objects are self-contained. Once ocreated, you cannot modify
the
genetic structure of a lifeform. But you can cut its head off for example,
nobody can
prevent you doing this.
If you are thinking of animals, what animal can be safely modified without
restriction?

If you don't want that someone touches the animal don't give it to him or
make a box(wrapper) around it.
Which computer programs or class-systems are perfect models of the real
world?

Programs are for the real world and are modelling real-life processes.
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?

It would be stupid to pass the galaxy to a human. all humans should be
contained in the galaxy.
the galaxy shoud manipulate the humans, not the other way around. if your
program is well designed
you will need no const correctness.
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.

C++ will still be important in 20 years. maybe not as important as today but
it will be there.
 
S

Sami Vaaraniemi

cody said:
Nobody should care about wheather an object is altered since you can always
safely alter a self-contained object. Additionally this encourages
programmed to make their objects more selfcontained and safe.

This is just wrong. Self-containment has little to do with constness.

Consider e.g., the CDC class in MFC that wraps the Windows device context.
CDC has an internal state that includes knowledge of all GDI objects
currently selected into the device context. The class is self-contained in
the sense that you cannot access the state directly (unless you access the
underlying device context handle but that is beside the point).

The class has a bunch of const methods, e.g., void DPtoLP(LPRECT lpRect)
const. The constness means that the user of the class can safely call the
member function and not have to worry whether the object's internal state
changes because of the call. This is a big deal.

If the method was not const, you'd have to pour over the documentation to
see whether the method changes the internal state. If the documentation is
vague on this point, you might end up saving the object's state prior to the
call and restoring it afterwards, just to be on the safe side. This would be
a major inconvenience and also a performance hit.

Regards,
Sami
 
A

Andreas Huber

[snip]
The base classes in acyclic visitor are abstract (no implementation),
and therefore, they can be expressed as interfaces. While C# does not
support multiple inheritance of classes, it does support multiple
inheritance of interfaces which makes implementing acyclic visitor in
C# trivial (see below).

Yep, I know. I just posted this because the OP made yet another unfounded
blanket statement:

<quote>
Multiple Inheritance is just bad style used by poor
programmers.
All Multiple Inheritance scenarios are best solved using composition
instead.
</quote>

Note that he isn't distinguishing between classes and interfaces...
That said, there are probably legitimate uses of MI where base
classes have implementation, too. In this case you could use
composition or delegates to get similar functionality.

I think that interface-only MI is enough for most scenarios and that it was
probably a good decision to not provide it for classes as that allows for
spectactular performance improvements with cross-casts.

Regards,

Andreas
 
C

cody

When you think Flexibility=="I can do every stupid thing I want, the
That is a child-like, absurd interpretation of Flexibility. Please
reconsider.

Erm..Please tell me your definition of Flexibility. Iam not sure what you
meant.
I don't want to pile on here - but computing will likely change so
dramatically in the next 5 years, that what happens in 10 years will hardly
be recognized as computing by those that are doing it now...

Hm. Very hard to tell, but lots of stuff have to be backward compatible
and consider the very huge codebase written in C++.
 
C

cody

Consider e.g., the CDC class in MFC that wraps the Windows device context.
CDC has an internal state that includes knowledge of all GDI objects
currently selected into the device context. The class is self-contained in
the sense that you cannot access the state directly (unless you access the
underlying device context handle but that is beside the point).

The class has a bunch of const methods, e.g., void DPtoLP(LPRECT lpRect)
const. The constness means that the user of the class can safely call the
member function and not have to worry whether the object's internal state
changes because of the call. This is a big deal.

If the method was not const, you'd have to pour over the documentation to
see whether the method changes the internal state. If the documentation is
vague on this point, you might end up saving the object's state prior to the
call and restoring it afterwards, just to be on the safe side. This would be
a major inconvenience and also a performance hit.


It doesn't bother me if a method puts a Pixel on that DC, it will have its
good reasons.
 
C

cody

Normally you don't have to care wheather an object is changed or not
since
Of course you must care! Whether an object is changed or not is crucially
important - the fact that an object is self-contained is completely
non-sequitor! You appear not to really understand the issues.


Maybe, so explain it please.
C++ seems (In my knowledge) to be the only language with such a feature
which
also means it is not that important as C++ programmers are telling, you are
just used to it.
Iam programming for a long time now and I never missed this feature. It was
useful in C++
but has no great use in other languages.
 
A

Andreas Huber

cody said:
Maybe, so explain it please.
C++ seems (In my knowledge) to be the only language with such a
feature which
also means it is not that important as C++ programmers are telling,
you are just used to it.
Iam programming for a long time now and I never missed this feature.
It was useful in C++
but has no great use in other languages.

Would you please let us know why exactly you think that const is useful in
C++ but not in C#? I personally don't see any difference that would affect
usefullness of const.

Regards,

Andreas
 
C

codymanix

The base classes in acyclic visitor are abstract (no implementation),
Yep, I know. I just posted this because the OP made yet another unfounded
blanket statement:

<quote>
Multiple Inheritance is just bad style used by poor
programmers.
All Multiple Inheritance scenarios are best solved using composition
instead.
</quote>

Note that he isn't distinguishing between classes and interfaces...

You cannot inherit from an interface, but you can implement them.
An interface is just a contract, you do not inherit something from them,
neither methods nor fields. A lot of people confuse that because the syntax
is the same.

Having said that, I hope you understand now that I was never talking about
interfaces.
 
C

cody

Normally you don't have to care wheather an object is changed or
Would you please let us know why exactly you think that const is useful in
C++ but not in C#? I personally don't see any difference that would affect
usefullness of const.


C++ makes a lot use of pointers (arrays, char*, pointers to objects) which
are not
selfcontained. everybody could alter a char* passed to a method, or even
delete[] it!
I could also pass the address to a local variable to a method as a pointer
and that
method could try to delete that pointer which will certainly crash your app.
I see big use for const with such types.

In C# you cannot delete something, additionally there is no such thing like
char* or
pointers (at least in safe mode)
Strings are immutable (immutability should be a property of the class, not
the object!).
Additionally since EVERY object is passed by reference (structs are very
rare in C#) you would have to precede almost every object variable/parameter
with a const if you
don't want to modify it. I don't want to write/maintain a such program!
 

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