How to prevent passed value types from being changed

T

Tony Johansson

Hi!

Assume I have variables such as width and height in main and pass these two
value types to a method called GetArea.
In this case the method can read the values of these two variables so that
it can calculate the area. The method can't change the value of the original
values that exist in main but it can change the formel copied value of
height and width so the returned result is based on the copied values in
GetArea.

But now to my question is it possible to prevent the two values that is
copied to the formel parameters in GetArea
to be changed in the GetArea method.
Below is an example that I call method GetArea from main and pass the value
of 2 for height and the value of 4 for width.
In the static method GetArea I change height by adding 1 and I add 1 to the
width.
So in main as you can see I say that "The area of 2 and 4 is 15 which is
not correct because that the height and width was changed in the GetArea
method by on.

So is it possible to use const or something else to prevent the copied
valued to be changed in the method GetArea ?

static int GetArea(int height, int width)
{
height++;
width++;
int result = height * width;
return result;
}

static void Main(string[] args)
{
int height = 2;
int width = 4;
Console.WriteLine("The area of: {0} and {1} is {2}", height,width,
GetArea(height, width));
}

//Tony
 
J

Jonathan Wood

No, you cannot prevent this. Your GetArea() method has a bug because it
returns the wrong result. The only place this can be changed is inside
GetArea(). It cannot be controlled by a method outside GetArea().

I can't imagine how this could be an issue. Maybe this is what you need?

static int GetArea(int height, int width, bool inc)
{
if (inc)
{
height++;
width++;
}
return height * width;
}
 
P

Peter Duniho

Tony said:
[...]
So is it possible to use const or something else to prevent the copied
valued to be changed in the method GetArea ?

static int GetArea(int height, int width)
{
height++;
width++;
int result = height * width;
return result;
}

Unfortunately, no. A "const" declaration has to be resolvable at
compile time, and "readonly" is not supported for method parameters and
local variables.

I agree that it could be useful to be able to declare method parameters
and locals as "readonly". Maybe a future version of C# will include
that. It's one of those very rare Java features that I miss in C#.

For some additional discussion on the topic, see this link:
http://stackoverflow.com/questions/443687/why-does-c-disallow-readonly-local-variables

(You can safely ignore the reply that claims it's because there's no CLR
support; as has been pointed out there, for method variables, there's no
need to have CLR support, since whether a method variable is being
modified can be detected at compile time).

In it, Jon Skeet (whom I respect highly) disagrees that it would be a
useful feature. I do agree with him that methods should be short enough
one can easily see _whether_ a variable is being modified or not. But
IMHO that's not the whole story. Self-documenting code includes being
able to identify that a variable _shouldn't_ be modified.

Just because you can see whether a variable is being modified or not,
that doesn't necessarily tell you whether that's a good idea or not.

I agree with his observation that the feature isn't used much in Java.
But that's not necessarily because it wouldn't add something useful to
the code. After all, in Java all accessible methods are overridable by
default, and probably should not be. But most people just ignore that,
and leave them as their default.

The fact that a feature is usually not used doesn't mean it's not
useful. It could just mean it's too inconvenient to be used regularly.

In the meantime, just be careful to not modify method variables that
shouldn't be modified. :)

Pete
 
H

Harlan Messinger

Tony said:
Hi!

Assume I have variables such as width and height in main and pass these two
value types to a method called GetArea.
In this case the method can read the values of these two variables so that
it can calculate the area. The method can't change the value of the original
values that exist in main but it can change the formel copied value of
height and width so the returned result is based on the copied values in
GetArea.

But now to my question is it possible to prevent the two values that is
copied to the formel parameters in GetArea
to be changed in the GetArea method.
Below is an example that I call method GetArea from main and pass the value
of 2 for height and the value of 4 for width.
In the static method GetArea I change height by adding 1 and I add 1 to the
width.
So in main as you can see I say that "The area of 2 and 4 is 15 which is
not correct because that the height and width was changed in the GetArea
method by on.

So is it possible to use const or something else to prevent the copied
valued to be changed in the method GetArea ?

static int GetArea(int height, int width)
{
height++;
width++;
int result = height * width;
return result;
}

static void Main(string[] args)
{
int height = 2;
int width = 4;
Console.WriteLine("The area of: {0} and {1} is {2}", height,width,
GetArea(height, width));
}

This is no different from putting into your code the statement

Console.WriteLine("The sum of 2 and 2 is 5");

and then asking if there is some way to prevent your code from making
false statements. The only way to prevent it from making false
statements is not to program it to do so. In your example, this means
not programming GetArea so that it produces the wrong result.

In case this doesn't completely satisfy you because you'd still like an
answer to your direct question, note that even if you *could* prevent
GetArea from changing the values of its arguments (you can't), it
wouldn't make any different because there's no way to prevent you from
writing

static int GetArea(int height, int width)
{
return -42;
}

So the real answer to your question is: the way to prevent your code
from producing the wrong result is not to write your code so that it
produces the wrong result!
 
P

Peter Duniho

Harlan said:
[...]
So the real answer to your question is: the way to prevent your code
from producing the wrong result is not to write your code so that it
produces the wrong result!

All due respect, you and Jonathan are missing the point.

The same logic you state above could be applied just as easily to class
fields. Do you have a field that should never be modified after
initialization? No need for "readonly" there either…just don't write
buggy code! (That is, code that "produces the wrong result").

The fact is, the language has a very large number of features that exist
solely for the purpose of helping us avoid writing buggy code. The
"readonly" keyword is such a feature, and being able to use it in the
context of a method, rather than just for class fields, is potentially
useful.

Don't get too hung up on Tony's specific example. It's obviously just
for illustration purposes. The real point is to consider a method that
has variables (parameters or locals) that should not change after
initialization, and how that might be represented in code so that the
compiler can emit an error when that requirement is violated.

IMHO, the reality is that for most situations, a method is simple
enough, and the implementation direct enough, that it's much less likely
someone would accidentally change the method after the fact such that a
method variable that needed to remain unchanged winds up modified. But,
the fact that the probability of a problem is low doesn't mean it's
non-existent, nor that supporting "readonly" for method variables is a
completely useless idea.

For sure, the suggestion to "not write code that produces the wrong
result" is not really helpful. I mean, that's the approach anyone
should be applying to all code they write. But good intentions aren't
enough. And if the compiler can help, why not let it?

Pete
 
H

Harlan Messinger

Peter said:
Harlan said:
[...]
So the real answer to your question is: the way to prevent your code
from producing the wrong result is not to write your code so that it
produces the wrong result!

All due respect, you and Jonathan are missing the point.

I don't think so, really. If you're writing a function the purpose of
which is to calculate the area of a rectangle, and in doing so your
understanding of how that should be done is so flawed that you think the
values of the arguments should be changed first, then how are you, the
same programmer, going to know that this is a function in which you need
to safeguard yourself from doing such a thing?
The same logic you state above could be applied just as easily to class
fields. Do you have a field that should never be modified after
initialization? No need for "readonly" there either…just don't write
buggy code! (That is, code that "produces the wrong result").

I see "readonly" as ensuring the integrity of not only a field but of
the class that contains it. It ensures that a field will never be
inadvertently changed after initialization, over all the methods and
properties of a class, possibly scores of them spanning pages and pages
of code, which may be worked on concurrently and over time by many
programmers, not all of whom, at any given time, have a 100% grasp on
the architecture of the class and the interrelationship among all of its
parts. Any one of the programmers seeing the "readonly" will take that
as an authoritative declaration of intent, as an architectural
specification, and won't (assuming the programmer is a responsible one)
go ahead and remove it unilaterally.

The case we've been presented involves a local variable that has no
architectural implications for any part of the class outside of the
current method. At any given time, probably only one programmer is
dealing with it, and any new programmer who takes up the code will grasp
the big picture of the entire routine after a short perusal. If that
programmer sees some specifier that fixes the value of these arguments,
and thinks for some reason that that should be removed, then the
programmer is going to break the method no matter what he does, because
he doesn't understand what it's supposed to do. He will do one of the
following

(1) remove the specifier

(2) do something like

int h = height;
int w = width;
h++;
w++;

(3) do something like
return (h + 1) * (w + 1);

No matter what, the result returned by the method will still be wrong,
and fixing the value of the arguments only changes *how* the programmer
will make it wrong.

Whatever the merits of having such a fixative feature might be, the
situation is really substantially different from the one involving readonly.
The fact is, the language has a very large number of features that exist
solely for the purpose of helping us avoid writing buggy code. The
"readonly" keyword is such a feature, and being able to use it in the
context of a method, rather than just for class fields, is potentially
useful.

Don't get too hung up on Tony's specific example. It's obviously just
for illustration purposes. The real point is to consider a method that
has variables (parameters or locals) that should not change after
initialization, and how that might be represented in code so that the
compiler can emit an error when that requirement is violated.

IMHO, the reality is that for most situations, a method is simple
enough, and the implementation direct enough, that it's much less likely
someone would accidentally change the method after the fact such that a
method variable that needed to remain unchanged winds up modified. But,
the fact that the probability of a problem is low doesn't mean it's
non-existent, nor that supporting "readonly" for method variables is a
completely useless idea.

OK, you and I are largely on the same page, at least in terms of our
assessment of the magnitude of the problem.
For sure, the suggestion to "not write code that produces the wrong
result" is not really helpful. I mean, that's the approach anyone
should be applying to all code they write. But good intentions aren't
enough. And if the compiler can help, why not let it?

Agreed. But in the much larger class-wide scenario, we depend a lot on
careful architecture to keep our code functioning within the framework
around which the class has been built. Without readonly, a programmer
might still perform *his* task *perfectly*, but might inadvertently
break something *else* that depended on him not taking certain liberties
with the data at his disposal. Inside a single method that you are
programming all by yourself, and all of which may even fit on the screen
in front of your face, the situation isn't generally so perilous. You
don't need to depend so much on a detailed architecture to prevent you
from hurting yourself.
 
P

Peter Duniho

Harlan said:
Peter said:
Harlan said:
[...]
So the real answer to your question is: the way to prevent your code
from producing the wrong result is not to write your code so that it
produces the wrong result!

All due respect, you and Jonathan are missing the point.

I don't think so, really.

Even so, I'm afraid you are.

Note that for the person missing the point, it can be difficult to get
to a point where they realize they are missing the point. That's part
and parcel of missing the point.

Just because you're paranoid, that doesn't mean people aren't out to get
you. And just because you don't think you're missing the point, that
doesn't mean you're not.
If you're writing a function the purpose of
which is to calculate the area of a rectangle, and in doing so your
understanding of how that should be done is so flawed that you think the
values of the arguments should be changed first, then how are you, the
same programmer, going to know that this is a function in which you need
to safeguard yourself from doing such a thing?

First, as I already pointed out, it is a mistake for you to get hung up
on the specific example. It's just an _example_. Other methods are not
always as simple as returning the product of two parameters.

Second, you are ignoring the fact that code needs maintenance. Even the
same person who wrote the code may, coming back months or years later,
not necessarily have an intuitive sense of the implementation details.
And for sure, a person who is not the original author would have no
reason to know that.

The more that code is self-documenting, the better.
I see "readonly" as ensuring the integrity of not only a field but of
the class that contains it.

Why should it's use be _restricted_ to that? And why is the integrity
of a method less important than the integrity of a class?
It ensures that a field will never be
inadvertently changed after initialization, over all the methods and
properties of a class, possibly scores of them spanning pages and pages
of code, which may be worked on concurrently and over time by many
programmers, not all of whom, at any given time, have a 100% grasp on
the architecture of the class and the interrelationship among all of its
parts. Any one of the programmers seeing the "readonly" will take that
as an authoritative declaration of intent, as an architectural
specification, and won't (assuming the programmer is a responsible one)
go ahead and remove it unilaterally.

Why are those benefits inapplicable to a method?

I have already specifically pointed out that the relative benefit is
less for "readonly" in a method. A major reason being the point that
the method is self-contained, not "spanning pages and pages of code".
But every other point you make about a class applies equally well to a
method, and inamsuch as "readonly" can assist in preventing problems,
it's just as useful for a method variable as for a class variable.
The case we've been presented involves a local variable that has no
architectural implications for any part of the class outside of the
current method.

Get past the "case we've been presented". Use some imagination, rather
than trying to deconstruct that particular example. The exact code Tony
posted is completely irrelevant. He's simply illustrating specific
usage, not a real-world motivation for the use of "readonly".
At any given time, probably only one programmer is
dealing with it, and any new programmer who takes up the code will grasp
the big picture of the entire routine after a short perusal.

That's a great idealistic way to approach method design. The real world
is not always so accommodating.
If that
programmer sees some specifier that fixes the value of these arguments,
and thinks for some reason that that should be removed, then the
programmer is going to break the method no matter what he does,

Straw man. You are presupposing a programmer who sees the
self-documenting code and ignores the documentation. So, of course with
that assumption you can invent unrealistic scenarios in which the
documentation becomes useless.

The realistic scenario is "that programmer sees some specifier that
fixes the value of these arguments, and understands that there is a
reason that the method relies on the value of those arguments being fixed".

You wouldn't assume a programmer would see a method return type of
"bool", and then change the method return type to "void" without
carefully considering the change. Why would you assume a programmer
would see "readonly" and then change it without careful considering.

Conversely, if you are assuming a programmer so dense that he sees the
"bool" return type and changes it to "void" without consideration at
all, then what use are any of the language constructs that declare the
intent and usage of the code? That programmer is ignoring every
safeguard put into the code, so by your logic we might as well just get
rid of all of those safeguards. After all, the rest of us can
successfully write correct code without them.

That approach is called assembly language. And I've written plenty of
it in my life already. I don't have any interest in going back.

In any case, either way your conclusion that "readonly" wouldn't be
beneficial for method variables is unsubstantiated.

Pete
 
H

Harlan Messinger

Peter said:
Harlan said:
Peter said:
Harlan Messinger wrote:
[...]
So the real answer to your question is: the way to prevent your code
from producing the wrong result is not to write your code so that it
produces the wrong result!

All due respect, you and Jonathan are missing the point.

I don't think so, really.

Even so, I'm afraid you are.

Pete, please don't tell me that I've missed your point just because I
disagree with it. You mentioned Jon Skeet disagrees with you too. Does
he get the same reaction from you?
Note that for the person missing the point, it can be difficult to get
to a point where they realize they are missing the point. That's part
and parcel of missing the point.

The person who thinks the other person is missing the point can be just
as wrong about that impression.

I had written a response piece by piece but I'm changing my approach and
consolidating it all right here.

You had written previously, "The fact that a feature is usually not used
doesn't mean it's not useful. It could just mean it's too inconvenient
to be used regularly." Then I don't see how you come to disagree with my
position that the feature isn't *as* useful within a method. If it's too
inconvenient to be used regularly, then it seems obvious to me that it
isn't *as* useful as it is in a context (class level) where it isn't
inconvenient to use regularly, and is in fact used regularly.

In several places, you asked me what the difference is between the
class-level situation and the method-level situation, after I had
already explained my view of the distinction.

After claiming that I had set up a strawman, you likened what I'd been
talking about--the treatment of arguments passed by value and local
variables within methods--to changing the return value of the method
from bool to void. Since I'd made it clear that I had been talking
exclusively about local references within methods that had no impact
whatsoever on anything outside the methods, your return value example
was a strawman.

Finally, you collapsed the entire structure, from application to class
to method, into the black-and-white, all-or-nothing conclusion that if I
hold the point of view that I have about what happens between methods,
then I might just as well forget about all safeguards everywhere and
might as well be programming in assembly language.

This is drastically unlike anything I've seen you write before and I
seriously don't understand what triggered it, and I'm really pretty
unhappy about the whole thing.
 
P

Peter Duniho

Harlan said:
Pete, please don't tell me that I've missed your point just because I
disagree with it. You mentioned Jon Skeet disagrees with you too. Does
he get the same reaction from you?

Did you go read his post? His point of disagreement is one regarding
relative utility, not this straw man about the GetArea() method being
buggy that you've put up. Specifically, he acknowledges that there is
_potential_ benefit, but that in practice he feels it's probably not
worth the trouble.

That's a lot different than asserting that because someone posted a
trivially buggy method, there is a valid counter-argument to the
suggestion of having "readonly" applicable to method variables on the
basis of that specific method example.
[...]
You had written previously, "The fact that a feature is usually not used
doesn't mean it's not useful. It could just mean it's too inconvenient
to be used regularly." Then I don't see how you come to disagree with my
position that the feature isn't *as* useful within a method.

Since I've said exactly that from the outset, I obviously do not
disagree with that statement. But that's not where you're missing the
point.
If it's too
inconvenient to be used regularly, then it seems obvious to me that it
isn't *as* useful as it is in a context (class level) where it isn't
inconvenient to use regularly, and is in fact used regularly.

Actually, "readonly" is just as inconvenient to use in a class as in a
method. IMHO, I would actually prefer that variables be "readonly" by
default and require specific marking to be mutable. (I think, in fact,
this is how F# does it, but I don't recall for sure).

In spite of the name "variable", I often wind up with more variables
that never change, and really ought to be "readonly". But I forget to
include "readonly", because it's relatively inconvenient to remember to
go around marking everything that could be "readonly".

Heck, the XSL language doesn't (and others don't) have _any_ mutable
variables. Granted, that works better in a functional language
environment (in fact, F# probably could've gotten away without mutable
variables too), but having a predominance of "readonly" variables would
probably be a good thing, programmatically speaking.
In several places, you asked me what the difference is between the
class-level situation and the method-level situation, after I had
already explained my view of the distinction.

No, your explanations all focused on the bogus GetArea() method, basing
your explanations on a completely irrelevant implementation.
After claiming that I had set up a strawman, you likened what I'd been
talking about--the treatment of arguments passed by value and local
variables within methods--to changing the return value of the method
from bool to void. Since I'd made it clear that I had been talking
exclusively about local references within methods that had no impact
whatsoever on anything outside the methods, your return value example
was a strawman.

Ironically, you again are missing the point. Which was: as part of your
argument against "readonly" for method variables, you have assumed a
programmer so stupid, they would change the return type of a method
without considering why the method actually had the specific return type.

That's the only kind of programmer that would also change a method
variable from "readonly" to not "readonly" without first considering why
the variable was marked that way, and understanding the implications of
their change.

You think I was talking about a language feature, when in fact I was
talking about the programmer. Again, missing the point.
Finally, you collapsed the entire structure, from application to class
to method, into the black-and-white, all-or-nothing conclusion that if I
hold the point of view that I have about what happens between methods,
then I might just as well forget about all safeguards everywhere and
might as well be programming in assembly language.

That is indeed the logical conclusion of your assertion that the
language need not include these kinds of code markings to ward against
programmer mistakes, yes.
This is drastically unlike anything I've seen you write before and I
seriously don't understand what triggered it, and I'm really pretty
unhappy about the whole thing.

I suspect that if you weren't missing the point, all would be clear.

In any case, I don't know why you should feel unhappy about the discussion.

If you are confident you are not missing the point, you should feel free
to simply ignore what I've written and leave it at that. I am not so
infallible that you should invest your own personal mood in what I
write. And even if I'm correct, being unhappy isn't a logical response.
It would, at worst, simply be an opportunity to learn something new
or, ever better, understand a point of view different from the one you
started with.

Logically, whether I'm right or wrong, there's no point in being unhappy
about it.

Pete
 
H

Harlan Messinger

Peter said:
No, your explanations all focused on the bogus GetArea() method, basing
your explanations on a completely irrelevant implementation.

No, they did not, which means emphatically that you missed *my* point.
 
H

Harlan Messinger

Peter said:
That is indeed the logical conclusion of your assertion that the
language need not include these kinds of code markings to ward against
programmer mistakes, yes.

Not only did I make no such general statement about the language
altogether, I spent a large chunk of my entire first post to you in this
thread distinguishing the very limited case of of variables visible only
within a method from the case of the class, where I find these kind of
code markings not only useful but important, and all the more so the
larger and more complex the class or the project containing it becomes.
So if your replies to me have been based on the premise that I had
asserted that the language need not include these kinds of code markings
*at all*, on *any level*, then they've been based on a false impression.
 
J

JeffWhitledge

I would just like to point out that both the subject line and the
original question specify "value types."

Now, value types are always just a copy. Therefore, whatever a method
chooses to do with those values is of no consequence to anything
outside of that method. If those parameter variables are modified,
that doesn't change any state, and it won't cause any side-effects.

This has nothing to do with the old argument over a potential "const"
modifier. Value types passed by value are always const anyway as far
as the caller is concerned.

Harlan Messinger's first post in this thread answers the original
question perfectly.
 
J

Jonathan Wood

Peter said:
All due respect, you and Jonathan are missing the point.

The same logic you state above could be applied just as easily to class
fields. Do you have a field that should never be modified after
initialization? No need for "readonly" there either…just don't write
buggy code! (That is, code that "produces the wrong result").

How can you compare this with class fields? Class fields will be around for
the life of the class. The variables in question are gone when the method
returns. Even if you could prevent them from being modified, there's nothing
to stop the method from copying them and setting them to another value. His
method simply does not do what he wants it to do.
The fact is, the language has a very large number of features that exist
solely for the purpose of helping us avoid writing buggy code. The
"readonly" keyword is such a feature, and being able to use it in the
context of a method, rather than just for class fields, is potentially
useful.

I disagree that a new keyword here would prevent the buggy code. As
mentioned, it could still be copied (yet again--it already has a copy) and
that value could be changed.
Don't get too hung up on Tony's specific example. It's obviously just for
illustration purposes. The real point is to consider a method that has
variables (parameters or locals) that should not change after
initialization, and how that might be represented in code so that the
compiler can emit an error when that requirement is violated.

If you can provide an example, I for one would be interested to see it.
Since all local variables are gone once the method returns, I fail to see
how this is an issue.
 
J

J.B. Moreno

Jonathan Wood said:
Peter Duniho wrote:

If you can provide an example, I for one would be interested to see it.
Since all local variables are gone once the method returns, I fail to see
how this is an issue.


Been using more VB than C# recently, so please forgive any and all
syntax problems with this, but


bool DangerWillRobinson(int height, ref width) {
width=10;

return true;
}

int GetArea(int height, int width) {
if DangerWillRobinson(height, ref width) {
return 42;
} else {
return height*width;
}
}

Now, if someone doesn't know what "ref" means they could inadvertently
change the value of width inside GetArea.

This illustrate how a readonly keyword applied to a parameter/argument
or variable would be beneficial -- you could have a compiler error when
using it as a ref/out parameter inside the method. But it also
illustrates that C# really doesn't need this, *because* it has ref/out
keywords -- you *always* know when a method call can the local
parameter.

The requirement that ref/out be present when calling as well as in the
signature, is an instance of C# being more "wordy" than VB, and to
EXCELLENT effect.

If I was dictating to the VB design team, I'd have them make them
optional in VB 10 and required in VB 11 (and then for that "extra"
touch, give a warning when declared but not used correctly).

As for the OP's request -- I don't see it as being useful, particularly
not for value types (it might be useful if you could guarantee a ref
type didn't have any of it's properties modified, but I don't see how
you could do that downstream of a particular method and so it'd be more
misleading than useful).
 
J

Jonathan Wood

J.B. Moreno said:
Been using more VB than C# recently, so please forgive any and all
syntax problems with this, but

bool DangerWillRobinson(int height, ref width) {
width=10;

return true;
}

int GetArea(int height, int width) {
if DangerWillRobinson(height, ref width) {
return 42;
} else {
return height*width;
}
}

I just don't get this. If you don't want width to be modified in
DangerWillRobinson, don't declare the parameter as ref. If you don't want
width to be modifed in GetArea, then pass a copy to DangerWillRobinson (in
the extremely rare case where you'd need to pass a variable you don't want
modified to a method that takes that variable by reference).

The C# syntax is such that it's plain as day that GetArea() may modify width
because C# requires you to place the ref keyword in the call. The question
was if there was a way to prevent a variable from changing. In this example,
that is so very easy.
This illustrate how a readonly keyword applied to a parameter/argument
or variable would be beneficial -- you could have a compiler error when
using it as a ref/out parameter inside the method. But it also
illustrates that C# really doesn't need this, *because* it has ref/out
keywords -- you *always* know when a method call can the local
parameter.

My problem with this is that the width argument to GetArea is a value type.
So GetArea has no possible way to modify the original value, no matter what
it does.

Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com
 
J

J.B. Moreno

Jonathan Wood said:
-snip-
The C# syntax is such that it's plain as day that GetArea() may modify width
because C# requires you to place the ref keyword in the call. The question
was if there was a way to prevent a variable from changing. In this example,
that is so very easy.

Which is why I went on to say that this is a solution looking for a
problem -- in C# the problem doesn't exist. You can force it as I did
above, but you have to force it and it's obvious when you do so.
My problem with this is that the width argument to GetArea is a value type.
So GetArea has no possible way to modify the original value, no matter what
it does.

It's not about modifying the original value, it's about guaranteeing
that all usage of width inside GetArea use the original value.

Look what calling DangerWillRobinson looks like from within VB

Function GetArea(ByVal height as Integer, ByVal width as Integer) as
Integer

If DangerWillRobinson(height, width) Then
return 42
Else
return height*width
End If
End Function


Just looking at the code, there's no indication that width will be
changed. Intellisense will show it, but not as clearly as C# would.
So, in VB a readonly keyword applied to value type parameters would be
useful -- BUT not as useful as adopting the C# syntax of ref/out.

Where might be useful is to have a readonly keyword for reference
types, as on thinking about it, it's not really that hard to do with
the MAJOR caveat that the class itself might modify it's state based
upon property/method calls.
 
J

Jonathan Wood

J.B. Moreno said:
Which is why I went on to say that this is a solution looking for a
problem

Then I guess I'll leave that to those who want to spend time looking for
problems -- ???
It's not about modifying the original value, it's about guaranteeing
that all usage of width inside GetArea use the original value.

So do you mean that the GetArea() method wants to ensure an argument will
not be changed (the calling method doesn't care)? Sort of like declaring a
const but from an argument? I haven't heard it articulated that way in this
thread but guess I can understand that point if that's what the OP was
asking for.
Just looking at the code, there's no indication that width will be
changed. Intellisense will show it, but not as clearly as C# would.
So, in VB a readonly keyword applied to value type parameters would be
useful -- BUT not as useful as adopting the C# syntax of ref/out.

Heh, well my condolences that you are stuck with VB.NET then. ;-) (Actually,
I used to use VB and even wrote a regular column for VBPJ, but there's no
way I'd use VB.NET.)
Where might be useful is to have a readonly keyword for reference
types, as on thinking about it, it's not really that hard to do with
the MAJOR caveat that the class itself might modify it's state based
upon property/method calls.

I guess I can see your point.
 
J

J.B. Moreno

Jonathan Wood said:
J.B. Moreno wrote:
-snip-

So do you mean that the GetArea() method wants to ensure an argument will
not be changed (the calling method doesn't care)? Sort of like declaring a
const but from an argument? I haven't heard it articulated that way in this
thread but guess I can understand that point if that's what the OP was
asking for.

I'm not 100% certain that's what the OP meant, but it's the only way
things even approach making sense -- from the callers respective
there's absolutely no difference between
return height * (width*2)
and
width *=2
return height * width

And in fact there might not even be a difference in the IL as the
compiler might optimize the intermediate assignment away.

-snip-
I guess I can see your point.

Well, it'd come with some other limitation that may not make it
worthwhile. The reference couldn't be used in an assignment and could
only be used as a parameter where the parameter was also readonly, this
last would mean that it wouldn't play well with existing code.

And to be clear, I'm not trying to advocate this, just saying that
unlike with value types, the caller does have a legitimate concern as
to what changes a method might make to a parameter.
 
J

Jonathan Wood

J.B. Moreno said:
Well, it'd come with some other limitation that may not make it
worthwhile. The reference couldn't be used in an assignment and could
only be used as a parameter where the parameter was also readonly, this
last would mean that it wouldn't play well with existing code.

Just like const in C++.

Jonathan
 
P

Peter Duniho

Jonathan said:
Just like const in C++.

Unfortunately, anyone who thinks that this discussion is about a
proposal to add a feature to C# that is like "const" arguments and
functions in C++ has missed the point.

"const" is about the mutability of the object itself. "readonly" is
only about the variable. Tony's question is clearly only about the
variable, and even reference type variables marked as "readonly" would
say nothing at all about the object itself; only the variable
referencing the object is affected.

There have been a number of tangential replies that really are about
something completely different from what Tony's asking about. IMHO,
it's important to understand that for anyone that intends or claims to
be addressing Tony's own original question.

Pete
 

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