How to pass a const object (read only object) to a method?

R

raylopez99

I'm posting this fragment from another thread to frame the issue
clearer.

How to pass an object to a function/method call in C# that will
guarantee not to change the object?* In C++, as seen below, you can
use the 'const' keyword in the function / method declaration. But how
to do this in C#?

*for example: "void Foo() const;"

Bonus question: how to do in C# this, from C++:
"const MyObjectReturnedThatCannotBeModified Foo(); "

RL
If your client lives, say, in Dallas, then,
when you want to reach it, you look where? in Dallas, no! if you are in
Seattle, you look at your cardfile holding your clients addresses. Now, if
one of your buddy (procedure), living in New York, ask to contact the said
client, you have two options: make a copy of your cardfile and 'pass' it to
him, that is 'by value', or you cant 'rent' him, for a while, your cardfile,
that will be 'passed by reference'. In both case, your New York buddy can
reach your client, in Dallas, and he can change your client to a not-client
anymore, quite permanently, sure, but, and there is a but, in the last case,
it can do much more, he can screw your cardfile too. And NEVER you ever
"passed" (ouch) the client it-self to your buddy.


So are you saying 'pass-by-value' is like 'constant' in C++ (which to
my newbie knowledge C# lacks) in that you can safely pass an object
to
a function so it cannot be manipulated to change the original? If
so,
please let me know how to do that, since honestly once I learned C# I
have yet to find how you can make a function/method take a 'read
only'
copy of a class (not a primitive type, but of a class). In fact,
Googling this confirmed this fact (see below). So I don't see how
pass-by-value is any 'safer' (or read-only) than 'pass-by-value' for
a
class passed.

RL


Googling on 'const', note the **** text ****--RL


The const keyword only applies to variables, which MSDN calls
“fields”. A field with the const keyword indicates that the field
cannot be changed. The value of the field must be initialized in the
declaration. Interestingly, attributes cannot be declared as const,
and furthermore, attributes referring to const fields can only have
getters, not setters.


****In C++, the const keyword was also used to indicate that the
method did not modify any variables:****
void Foo() const;


****or that the method returned a reference that could not be
modified:****
const int& Foo();


or that the parameter being passed as a reference could not be
modified by the method:
void Foo(const int& i);


which could lead to some ridiculous but valid statements:
const int& Foo(const int& i) const;


Happily, C# treats the keyword const with only one meaning.


Declaring fields as const protects both you and other programmers
from
accidentally changing the value of the field. Also note that with
const fields, the compiler performs some optimization by not
declaring
any stack space for the field.


Furthermore, const can only be applied to intrinsic types. You can’t
say:
const HasConstField hcf2=new HasConstField();
 
J

Jon Skeet [C# MVP]

I'm posting this fragment from another thread to frame the issue
clearer.

How to pass an object to a function/method call in C# that will
guarantee not to change the object?*  In C++, as seen below, you can
use the 'const' keyword in the function / method declaration.  But how
to do this in C#?

You can't. There's no equivalent in C#.

On the matter of only being able to apply "const" to certain types,
you can make any field readonly. However, be aware that that only
affects the field itself - you can have a readonly StringBuilder field
but still append to referenced object.

The difference between const and readonly is that const values are
baked into the referer's code - so it's inappropriate for things like
version numbers which may change. It really should only be used for
genuinely constant values.

Jon
 
R

raylopez99

You can't. There's no equivalent in C#.

Thanks Jon Skeet. Well that sucks. How can you prevent a function/
method from 'accidentally' modifying an object reference? Other than
being very careful when you code? Seems like this is a defect in C#,
or a feature desperately needed in C#, kind of like the glorified type
sensitive Case statement you once said is lacking in C# if memory
serves me right.

RL
 
J

Jon Skeet [C# MVP]

raylopez99 said:
Thanks Jon Skeet. Well that sucks. How can you prevent a function/
method from 'accidentally' modifying an object reference?

If your type is mutable, you can't. That's one of the benefits of
immutable types.
Other than being very careful when you code? Seems like this is a
defect in C#, or a feature desperately needed in C#, kind of like the
glorified type sensitive Case statement you once said is lacking in
C# if memory serves me right.

Well, switch/case could certainly be improved. I wouldn't say that
const is "desperately lacking". We seem to have managed pretty well
without it for several years.

It would be nice, but only if:

a) *all* standard libraries supported it appropriately
b) it couldn't be cast away (as it can in C++)
c) a nice syntax could be found

Point c is the tricky one. By the time you've got generics a couple of
layers deep, there can be several types which *might* be const. Or even
a plain array - do you really want to be talking about a
const (const Person)[] to be a const array of const Person elements? I
haven't seen nice syntax to get round that kind of thing yet.
 
A

Arne Vajhøj

raylopez99 said:
Thanks Jon Skeet. Well that sucks. How can you prevent a function/
method from 'accidentally' modifying an object reference? Other than
being very careful when you code? Seems like this is a defect in C#,
or a feature desperately needed in C#,

If you use the standard C# style, then you very rarely need it.

You should not try and code C++ in C#.

If you for some domain specific reason absolutely need this
feature, then code in C++.

Arne
 
C

Cor Ligthert[MVP]

Ray,

Serialize it, Deserialize it and pass the result then.

Cor

"raylopez99" <[email protected]> schreef in bericht
I'm posting this fragment from another thread to frame the issue
clearer.

How to pass an object to a function/method call in C# that will
guarantee not to change the object?* In C++, as seen below, you can
use the 'const' keyword in the function / method declaration. But how
to do this in C#?

*for example: "void Foo() const;"

Bonus question: how to do in C# this, from C++:
"const MyObjectReturnedThatCannotBeModified Foo(); "

RL
If your client lives, say, in Dallas, then,
when you want to reach it, you look where? in Dallas, no! if you are in
Seattle, you look at your cardfile holding your clients addresses. Now, if
one of your buddy (procedure), living in New York, ask to contact the said
client, you have two options: make a copy of your cardfile and 'pass' it
to
him, that is 'by value', or you cant 'rent' him, for a while, your
cardfile,
that will be 'passed by reference'. In both case, your New York buddy can
reach your client, in Dallas, and he can change your client to a
not-client
anymore, quite permanently, sure, but, and there is a but, in the last
case,
it can do much more, he can screw your cardfile too. And NEVER you ever
"passed" (ouch) the client it-self to your buddy.


So are you saying 'pass-by-value' is like 'constant' in C++ (which to
my newbie knowledge C# lacks) in that you can safely pass an object
to
a function so it cannot be manipulated to change the original? If
so,
please let me know how to do that, since honestly once I learned C# I
have yet to find how you can make a function/method take a 'read
only'
copy of a class (not a primitive type, but of a class). In fact,
Googling this confirmed this fact (see below). So I don't see how
pass-by-value is any 'safer' (or read-only) than 'pass-by-value' for
a
class passed.

RL


Googling on 'const', note the **** text ****--RL


The const keyword only applies to variables, which MSDN calls
“fields”. A field with the const keyword indicates that the field
cannot be changed. The value of the field must be initialized in the
declaration. Interestingly, attributes cannot be declared as const,
and furthermore, attributes referring to const fields can only have
getters, not setters.


****In C++, the const keyword was also used to indicate that the
method did not modify any variables:****
void Foo() const;


****or that the method returned a reference that could not be
modified:****
const int& Foo();


or that the parameter being passed as a reference could not be
modified by the method:
void Foo(const int& i);


which could lead to some ridiculous but valid statements:
const int& Foo(const int& i) const;


Happily, C# treats the keyword const with only one meaning.


Declaring fields as const protects both you and other programmers
from
accidentally changing the value of the field. Also note that with
const fields, the compiler performs some optimization by not
declaring
any stack space for the field.


Furthermore, const can only be applied to intrinsic types. You can’t
say:
const HasConstField hcf2=new HasConstField();
 
A

Arne Vajhøj

rossum said:
When I have a problem like this I just make a deep enough copy of the
object I do not want changed and pass the copy to the function. I
carry on working with the original, which I am sure has not been
changed by the function.

That is a possibility, but depending on the objects and how many
times it has to be done, then it may have a performance impact.

Arne
 
R

raylopez99

Ray,

Serialize it, Deserialize it and pass the result then.

Cor

Thanks Cor and Rossum. I did not realize until now that a Deep Clone
is the way to go if you don't want a class to be mutable when passed
to a function. Deep Clone aka copy constructor in C++.

RL
 

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