Why is this bad practice

P

philipl

hi,

while reading .net framework sdk, it says that the following is bad
practice, then it goes on to give an example with the very same
instance of this 'bad practice'. Can someone comment on this, is it
good or bad?

//msdn
public int Number
{
get
{
return number++; // Don't do this
}
}


then further on.....

Example 2
In this example, two classes, Cube and Square, implement an abstract
class, Shape, and override its abstract Area property. Note the use of
the override modifier on the properties. The program accepts the side
as an input and calculates the areas for the square and cube. It also
accepts the area as an input and calculates the corresponding side for
the square and cube.

// overridding_properties.cs
// Overriding properties
using System;
abstract class Shape
{
public abstract double Area
{
get;
set;
}
}

class Square: Shape
{
public double side;

// Constructor:
public Square(double s)
{
side = s;
}

// The Area property
public override double Area
{
get
{
return side*side ;
}
set
{
// Given the area, compute the side
side = Math.Sqrt(value);
}
}
}

class Cube: Shape
{
public double side;

// Constructor:
public Cube(double s)
{
side = s;
}

// The Area property
public override double Area
{
get
{
return 6*side*side;
}
set
{
// Given the area, compute the side
side = Math.Sqrt(value/6);
}
}
}

public class MainClass
{
public static void Main()
{
// Input the side:
Console.Write("Enter the side: ");
string sideString = Console.ReadLine();
double side = double.Parse(sideString);

// Compute areas:
Square s = new Square(side);
Cube c = new Cube(side);

// Display results:
Console.WriteLine("Area of a square = {0:F2}",s.Area);
Console.WriteLine("Area of a cube = {0:F2}", c.Area);

// Input the area:
Console.Write("Enter the area: ");
string areaString = Console.ReadLine();
double area = double.Parse(areaString);

// Compute sides:
s.Area = area;
c.Area = area;

// Display results:
Console.WriteLine("Side of a square = {0:F2}", s.side);
Console.WriteLine("Side of a cube = {0:F2}", c.side);
}
}
Input
4
24
Sample Output
Enter the side: 4
Area of a square = 16.00
Area of a cube = 96.00
Enter the area: 24
Side of a square = 4.90
Side of a cube = 2.00
 
J

Jon Skeet [C# MVP]

while reading .net framework sdk, it says that the following is bad
practice, then it goes on to give an example with the very same
instance of this 'bad practice'. Can someone comment on this, is it
good or bad?

//msdn
public int Number
{
get
{
return number++; // Don't do this
}
}

Where exactly does that occur in the example that follows? Note that
the bad practice here is that fetching the Number also *changes* it -
something that I can't see happening in the example you gave.
 
V

Vincent Lascaux

//msdn
public int Number
{
get
{
return number++; // Don't do this
}
}

Here you wont get the same answer every time you read the Number property...
It's bad : I expect that x.Number + x.Number == 2*x.Number, but it's not the
case. You should not modify any variable within the get member of a
property...
// The Area property
public override double Area
{
get
{
return side*side ;
}

That's ok : I'll get the same answer every time I read the Area property
(provided 'side' doesnt change)...
 
J

Joe Kasta

I"m not sure how it's implemented in the .NET framework, but ++number is
usually preferred to number++.

Why? Some implementations I"ve seen use this to mean number++

{
int temp = number;
number = number + 1;
return temp;
}
Note, the number is incremented an another object is allocated. But in
++number,

{
number = number + 1;
return number;
}

No extra step or allocation. Not sure of .NET does it this way, but it's
good practice to use, where you can.

=J
 
J

Jon Skeet [C# MVP]

Joe Kasta said:
I"m not sure how it's implemented in the .NET framework, but ++number is
usually preferred to number++.

That may be true in some particualr languages, but generalising it to
"usually" strikes me as a bad idea.
Why? Some implementations I"ve seen use this to mean number++

{
int temp = number;
number = number + 1;
return temp;
}
Note, the number is incremented an another object is allocated.

Where's the object here? In this case it's just integers, so no objects
are being allocated at all. In the case where objects *are* allocated,
a new object should be allocated in either way, rather than updating
the current one. The only difference is that the stack needs to be one
bit larger - and then only if it's actually being used in the middle of
an expression, in which case the difference is semantically important
anyway. I trust the JIT to optimise the two equally when they're
statements on their own.

No extra step or allocation. Not sure of .NET does it this way, but it's
good practice to use, where you can.

I disagree with the idea that one should take idioms from one
language/platform and apply them indiscriminately to others. I
personally find number++; more readable, and will continue to do so
until I've seen some evidence that shows it makes any difference in the
actual context in which I'm using it.
 
S

Stu Banter

Joe Kasta said:
I"m not sure how it's implemented in the .NET framework, but ++number is
usually preferred to number++.

I think your statement holds little truth. Whether I choose prefix or
postfix operators depends entirely on the situation at hand. I wouldn't like
to see this in a program a lot:

for (int i = 0 ; i < MaxValue; ++i)
{
myArray [i-1] = (i-1) * (i-1); // or whatever you want to do with it....
}


Besides, I think the point of the OP's example of bad practise is a
different one altogether, and prefixed the idea would be as bad a practice
as any other example in which a var gets altered in a get accessor.

The idea of a get accessor is the var is now available to the outside world
like it would be a public var, so I'd EXPECT its behaviour to be similar,
and not have any modifying actions performed on it. get & set were not meant
to be just another method. I'd have expected it to be illegal even to modify
the key value in the get accessor...
 
V

Vincent Lascaux

I think your statement holds little truth. Whether I choose prefix or
postfix operators depends entirely on the situation at hand. I wouldn't like
to see this in a program a lot:

for (int i = 0 ; i < MaxValue; ++i)
{
myArray [i-1] = (i-1) * (i-1); // or whatever you want to do with it....
}

Would you definitly prefer this ?
for(int i = 0; i < MaxValue; i++)
{
myArray [i-1] = (i-1) * (i-1); // or whatever you want to do with it....
}
In this example, ++i and i++ are interchangeable because their value is not
read (the value of 'i' is read, but after ++i or i++, i has the same value)

++i is, IMHO, far more intuitive than i++. I think ++i should be used every
where, but when i++ is what you mean (and it's rare to need to use i++).
 
J

Jon Skeet [C# MVP]

++i is, IMHO, far more intuitive than i++. I think ++i should be used every
where, but when i++ is what you mean (and it's rare to need to use i++).

And that's fine for you, but I suspect (given the balance of code that
I've read) that most other people prefer i++; when it's the same as
++i; - I know I do. (I like to read what I'm incrementing before I see
that I'm going to increment it.)

This is one of the issues which I believe is down to pure personal
taste.
 
V

Vincent Lascaux

And that's fine for you, but I suspect (given the balance of code that
I've read) that most other people prefer i++

I suspect that most teacher teach i++ rather than ++i (I don't know why :
++i is easier to teach and more performant than i++).
I like to read what I'm incrementing before I see
that I'm going to increment it.

I agree with that point : i++ is more readable (provided you dont need to
understand what it does ;))
 
J

Jon Skeet [C# MVP]

Vincent Lascaux said:
I suspect that most teacher teach i++ rather than ++i (I don't know why :
++i is easier to teach and more performant than i++).

Ah - now you're making measurable claims. Do you have any evidence that
++i performs better in C#/.NET than ++i does? A quick test of:

static void Foo()
{
int i=0;
i++;
Console.WriteLine (i);
}

static void Bar()
{
int i=0;
++i;
Console.WriteLine (i);
}

shows the same IL being generated for both.
I agree with that point : i++ is more readable (provided you dont need to
understand what it does ;))

I'd say that even if you *do* know what it does, it's more readable.
 
V

Vincent Lascaux

shows the same IL being generated for both.

How do you see the generated IL ?
I'd say that even if you *do* know what it does, it's more readable.

When I read ++i, I think "here, i is incremented". When I read i++, I think
"ok, i is incremented, but the value of i++ is the old value of i" or "this
expression will be evaluated and i will be incremented after".
What I have seen is a lot of people thinking "here, i is incremented" when
they read i++. And that leads to errors when they use i++ in expressions...
 
J

Jon Skeet [C# MVP]

Vincent Lascaux said:
How do you see the generated IL ?

Use ILDASM.
When I read ++i, I think "here, i is incremented". When I read i++, I think
"ok, i is incremented, but the value of i++ is the old value of i" or "this
expression will be evaluated and i will be incremented after".
What I have seen is a lot of people thinking "here, i is incremented" when
they read i++. And that leads to errors when they use i++ in expressions...

But you really only get much *choice* about which to use when it's
standing alone. I very rarely use it within another expression, eg:

x = i++;
y = ++i;

I'd almost always write the above as:

x = i;
i++;

i++;
y=i;

just because it's clearer even when you *are* clear what the two
operators mean.

So essentially, the way I write code, the two operators are almost
always identical, but I find i++; easier to read.
 
D

Daniel Billingsley

If a person doesn't readily understand what i++ does when they see it, then
this discussion is way over their head and they wouldn't know the difference
between ++i and i++ anyway. Your last statement is laughably ridiculous to
the point that you're not really contributing anything sensible to this
discussion.
 
D

Daniel Billingsley

Jon, "readability" is a subjective thing of course, and unless someone can
demonstrate some psychological testing that demonstrates which is the case
it is simply a matter of personal taste. Having said that, I will say that
anecdotally speaking, looking at other people's code you will see i++ 100
times for every once you see ++i (at least), and that would suggest that i++
is probably much more quickly grasped... much like when you read you don't
actually have to spend any time processing the sequence of letters y-o-u
because your brain instantly recognizes that pattern as the word "the" - but
come across t-h-e-e used to mean the same thing and there would be a
definite slowdown because of unfamiliarity.

What I'm trying to say is you've demonstrated that Vincent is clearly wrong
on his first point (performance). He is also almost certainly wrong on his
second point, generally speaking, but I know of no evidence proving it so.
 
J

Jon Skeet [C# MVP]

Daniel Billingsley said:
Jon, "readability" is a subjective thing of course, and unless someone can
demonstrate some psychological testing that demonstrates which is the case
it is simply a matter of personal taste.

I wouldn't go that far - there are certain things which are *obviously*
more readable in general without needing a psychological study to prove
it. However, I agree that on many things it *can* be a matter of
personal taste.
Having said that, I will say that
anecdotally speaking, looking at other people's code you will see i++ 100
times for every once you see ++i (at least), and that would suggest that i++
is probably much more quickly grasped... much like when you read you don't
actually have to spend any time processing the sequence of letters y-o-u
because your brain instantly recognizes that pattern as the word "the" - but
come across t-h-e-e used to mean the same thing and there would be a
definite slowdown because of unfamiliarity.
Excatly.

What I'm trying to say is you've demonstrated that Vincent is clearly wrong
on his first point (performance). He is also almost certainly wrong on his
second point, generally speaking, but I know of no evidence proving it so.

Right - we've only got anecdotal evidence (the way people actually
write code) and our own personal tastes. It's not necessarily proof,
but it's good enough for me :)
 
V

Vincent Lascaux

If a person doesn't readily understand what i++ does when they see it,
then
this discussion is way over their head and they wouldn't know the difference
between ++i and i++ anyway.

If they use i++, they know partly what it does : if you ask somebody
that is not very self-confident with C# or C++ what i++ does, he will
certainly say "it increments i". I bet he wont know that it's value is the
old value of the variable, and that it doesnt have the same meaning as
'i=i+1'.
So I think it's important they use the tool that best suit what they
think : ++i, that is completly equivalent to i=i+1.
Your last statement is laughably ridiculous to
the point that you're not really contributing anything sensible to this
discussion.

Thanks for this argued reflection...
It looks like I dont understand you : my point is '++i' does what you think,
'i++' may be easier to read if you dont have to think about what it does (ie
its return value). I'm happy it made you laugh.
Reading again, dont you think *your* last statement is more ridiculous than
mine ? Do you really think your last statement contribute to this discussion
?

You are true about the performances : I studied C++ before C#, where ++i
might be more performant than i++ (if i is something complex, as an iterator
for example). But it is still a good habit to use ++i instead of i++ if you
plan to learn C++ (if you already know C++ you should already write ++i
;))...
 
N

Niall

Even if ++i and i++ generated different IL, and ++i was faster, I think that
getting down to this level of granularity when analysing performance in a
managed environment will not yield noticeable results. I would be hard
pushed to think of a situation where the work done inside a loop had less of
an impact on performance than incrementing the index or some other counter.

When it comes to readability, I'm in the i++ group. I agree with Jon, that I
don't generally write things like x = ++y, because it's usually much more
readable in terms of the business process code is performing to separate the
actions. In the end, the user may have to wait a few more clock cycles for
their result, but I'm sure they'll be glad that I can read the code more
easily! :p

Niall
 
V

Vincent Lascaux

When it comes to readability, I'm in the i++ group. I agree with Jon, that
I
don't generally write things like x = ++y

If you dont write such things, then i++ and ++i has the exact same meaning,
and ++i is what you mean. But I agree with you (even if it is laughably
ridiculous) that i++ is more easy to read than ++i because we are used to
put the operator after the variable (like in i+1). But it's not really hard
to read ++i, and I bet your brain will learn that really quickly... I still
think that it's sad that people are tought to write i++, and actually write
i++ when the meaning of ++i is much more simple.
 
N

Niall

Maybe it's because it was called C++ and not ++C... who knows what people
would be thinking these days if they had called it ++C :p

Niall
 
J

Jon Skeet [C# MVP]

Vincent Lascaux said:
You are true about the performances : I studied C++ before C#, where ++i
might be more performant than i++ (if i is something complex, as an iterator
for example). But it is still a good habit to use ++i instead of i++ if you
plan to learn C++ (if you already know C++ you should already write ++i
;))...

This is where I disagree violently - learning an idiom in one language
*just* because it's more suitable in a different language is a really
bad idea. In fact, I'd almost be tempted to write i++; in C#
*precisely* because in C++ the preferred idiom may be ++i;. It's very
important to make sure that you use the right idioms for the language
you're actually writing in, and the more hints you can give that you
know that you're *not* writing in C++ when you're actually writing in
C#, the better.

Some of the worst code I've seen has been written by people trying to
twist idioms in one language until they work in another, rather than
re-evaluate their idioms to start with.
 

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