const objects on a function level?

P

PGP

How do i pass a const object to a function in C#?
I mean the equivalent of
void Func(const MyObject obj)
{
}
 
J

Jeff Johnson

How do i pass a const object to a function in C#? I mean the equivalent of
void Func(const MyObject obj)
{
}

I don't believe C# supports this functionality directly. I think the general
workaround is to clone the object before passing it to the function so if
anything gets modified in the function, the original object is not altered.
A deep copy would most likely be required.
 
L

Larry Smith

How do i pass a const object to a function in C#? I mean the equivalent of
void Func(const MyObject obj)
{
}

There is no analogue for this in C# AFAIK (a significant language
short-coming IMO). BTW, you should be passing by reference in your call
above (or by pointer but a reference is arguably better for "const"
objects).
 
J

Jeff Louie

PGP... This functionality can be achieved by using immutable objects or
by
wrapping the mutable object in an immutable wrapper object and passing
the
immutable wrapper object to the function.

Regards,
Jeff
 
P

PGP

Larry Smith said:
There is no analogue for this in C# AFAIK (a significant language
short-coming IMO). BTW, you should be passing by reference in your call
above (or by pointer but a reference is arguably better for "const"
objects).
All objects are passed by reference by default. Please elaborate if i missed
anything.
 
P

Peter Morris

How do i pass a const object to a function in C#? I mean the equivalent of
void Func(const MyObject obj)
{
}

If you mean "const" as in I can't do this


public void Blah(MyObject obj)
{
obj = null; //This would be disallowed
}

Then there is no performance gain in doing this, it merely stops you from
reassigning the value in the source code. In my opinion the only reason to
do this would be if the person writing the method wasn't very bright :)

Even if the parameter were constant it wouldn't stop you from doing this....


public void Blah(Person person)
{
person.Name = "I have changed it";
}


If you want a kind of "deep" constant value (i.e. not able to alter the
properties of the parameter) then you would either

A: Need to either pass a cloned version which means you have to remember to
do that every time (and that is going to trip you up at some point in the
future)
B: Change your method so that you don't need to change anything on the
parameter
C: Clone the value at the top of your method

public void Blah(Person person)
{
person = (Person)person.Clone();
person.Name = "I have changed it, but not the original object only the
copy!";
}
 
L

Larry Smith

Larry Smith said:
All objects are passed by reference by default. Please elaborate if i
missed anything.

Not in C++ where objects are passed by value. For non-POD types in
particular, meaning most user-defined classes (usually), your function
should read like this instead:

void Func(const MyObject &obj)

Otherwise, without the "&", the object is passed by value which results in
an inefficient copy of the original argument.
 
P

PGP

Peter Duniho said:
I don't understand Larry's comment either (the application of "const" in
C++ depends on whether something is passed by value or by reference, but
it's useful in both scenarios), but it's not true that "all objects are
passed by reference by default". How something is passed to a method
depends on the _argument_, not the object. And only arguments declared
with "ref" or "out" are passed "by reference". Otherwise, they are passed
"by value".

When passing a reference type by value, it's true that a reference is the
value that's passed. But the _passing_ itself is "by value".

Pete
Peter
Thanks for elaborating that. In fact, the essence of what i understood still
holds.
It is good to remember that generally types other than PODs and structs are
reference types in C# and the reference is passed by value which is in
effect
the same as object& as Larry is referring to, but i think Larry is still
answering
in C++ context.
Also, so far i understand a "value type" can be passed by reference by using
the
"ref" keyword, but there is no way to pass a reference type by value.
Priyesh
 
B

Ben Voigt [C++ MVP]

Peter said:
Not sure what you mean here. A reference type in C# passed by value
is most like passing a pointer in C++ (for example, to a method with a
declaration like "void method(char *pch)", in which a reference to a
char is passed by value). Passing by reference in C++ ("void
method(char &psz)") is just like passing by reference in C#.


That's not true, and your mistake is the crux of my point. You can in
fact pass a reference type by value in C#, and what you get is the
reference. That's what the value of a reference type is.

Which is just another way of saying you never pass the content of a
reference type by value, you can only pass the value of a tracking handle to
the data. There is NO way of getting rid of the indirection.
 
B

Ben Voigt [C++ MVP]

Peter Duniho said:
[...]
That's not true, and your mistake is the crux of my point. You can in
fact pass a reference type by value in C#, and what you get is the
reference. That's what the value of a reference type is.

Which is just another way of saying you never pass the content of a
reference type by value, you can only pass the value of a tracking
handle to the data. There is NO way of getting rid of the indirection.

True. That's what it means for something to be a reference type. The
type is the _reference_ to the object, not the object itself.

But that doesn't change the fact that there's a difference between passing
a reference type by value and a reference type by reference (or a value
type by reference, for that matter).

Yes, but...

That distinction doesn't influence the current discussion in any way. It's
good to be precise, even pedantic, for the sake of future readers, but we
have to do so without confusing the original issue.

The issue is whether you can have pass-by-value i.e. copy-on-call semantics
for instances of a reference type. The answer is "no, you cannot". Not
because reference type parameters are always pass-by-reference (they
aren't), but because the variable that is passed by value is a handle, not
the content itself, so only the handle is copied, and not the content.
There is no way to declare a method (member function) to receive a copy of
the *object* referred to in the actual parameter. The copy must be done by
the caller, often via ICloneable.Clone
 

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