Constant parameters

  • Thread starter Thread starter Peter Kirk
  • Start date Start date
P

Peter Kirk

Hi,

I have a method which receives an argument of which I need to change some
values before I use it. But I don't want to alter the object for the caller.
How do I achieve this? Do I need to make a local copy of the obect in my
method, or otherwise "manually" ensure that the object remains unaltered
when my method exits?

For example, see the method below. Here, the caller supplies "anArgument",
which my method alters, but I don't want the caller to see this change -
that is, I want the caller's object to remain unaltered when my method
exits.

public IResult DoSomeStuff( IArg anArgument )
{
IResult result = new MyResult();
anArgument.Value = anArgument.Value + 1;
return result;
}

Thanks,
Peter
 
C# always takes objects by reference only. Suppose the passed parameter
should not be altered then it can be declared as readonly field.

Some thing like this..

public class Class1
{
public readonly string teststring;

Class1(string testmessage)
{
this.teststring = testmessage
}


}


void TestMethod(string arg)
{
arg += "is an Message"
}

Class1 tempclass1 = new Class1("Message");
Testmethod(tempclass1.teststring);

Though the arg is changed, the value of tempclass1.teststring remains
unaltered.

Regards
Prakash Prabhu K
 
Peter Kirk said:
Hi,

I have a method which receives an argument of which I need to change some
values before I use it. But I don't want to alter the object for the
caller. How do I achieve this? Do I need to make a local copy of the obect
in my method, or otherwise "manually" ensure that the object remains
unaltered when my method exits?

For example, see the method below. Here, the caller supplies "anArgument",
which my method alters, but I don't want the caller to see this change -
that is, I want the caller's object to remain unaltered when my method
exits.

public IResult DoSomeStuff( IArg anArgument )
{
IResult result = new MyResult();
anArgument.Value = anArgument.Value + 1;
return result;
}

Thanks,
Peter

Hi Peter.

A class should be self-contained. Hence a method of some class should not
try to copy an object; the object should know how to copy itself. The
pattern is called Cloning.

In .NET there is a interface called IClonable which is useless in .NET 1.1
(as it force you to return Object) but will be powerful in 2.0 with generics
(as it may return type of itself).

I would suggest you add the method .Clone() to your class but without
implementing IClonable.

Simple example:

public class Person
{
string name;
int age;

public Person Clone()
{
Person p = new Person();
p.name = this.name;
p.age = this.age;
return p;
}
}

Happy Coding
- Michael S
 
Michael S said:
Hi Peter.

A class should be self-contained. Hence a method of some class should not
try to copy an object; the object should know how to copy itself. The
pattern is called Cloning.

In .NET there is a interface called IClonable which is useless in .NET 1.1
(as it force you to return Object) but will be powerful in 2.0 with
generics (as it may return type of itself).

I would suggest you add the method .Clone() to your class but without
implementing IClonable.

Simple example:

public class Person
{
string name;
int age;

public Person Clone()
{
Person p = new Person();
p.name = this.name;
p.age = this.age;
return p;
}
}

OK, thanks for the answer. I had done it like:

public class Person
{
string name;
int age;

public Person(string name, int age)
{
this.name = name;
this.age = age;
}

public Person(Person p)
{
this.name = p.name;
this.age = p.age;
}

...methods for person etc...
}

Where I have a constructor which copies a supplied Person. Are there
disadvantages to this approach over the Clone approach you suggest? In my
method where I use a person, I do this:

public IResult DoSomeStuff( Person person )
{
IResult result = new MyResult();

Person localPerson = new Person(person);

// now I work with "localPerson", not "person" ...

return result;
}


But basically, I do myself need to code the functionality of maintaining the
state of the argument object.

Thanks,
Peter
 
This is really interesting Peter.

In Java, the recent fad is to make everything immutable. Hence there are no
getters and setters but every object is set by the constructor and then
creating new objects via the constructor is your only option when you wanna
change values. If you ask me this is a loose-loose way of doing things.

In .NET we tend to have mutable objects. Hence a object will (most often) be
instanced with defualt values and we use properties to get/set values.
Overloaded constructors are considered shortcuts or binders.

I like the cloning approach, as it shows very clearly that you are indeed
making a copy of the object.
But I'm not sure I like the overloaded constructor with a default
constructor. I think it should be either way.

1. Just a default constructor. Consumer should set properties. (.NET-style)
2. A overloaded constructor. Default constructor is private. (Java-style)

Anyways, I think using a Clone method is better than having a overloaded
constructor:

Person anotherPerson = firstPerson.Clone(); // I like this. For me it
clearly says i will have a copy.
Person anotherPerson = new Person(firstPerson); //I don't like this. Will I
get a copy? Will they marry or does anotherPerson just hump the first one?
What is the state of firstPerson after being humped? Must I check if either
one or both have a wedding-ring? =)

In the .NET framework we have stuff like myCommand = new
SqlCommand("sql...", myConnection) that clearly join a command to a
connection. This is why I don't like the having constructors for cloning as
it implies inter-references rather than copying in .NET.

And never forget the last words of Mahatma Gandhi:
- When your coding C# in a mutual world, don't try to pretend it's immutal.
That's bad for karma!

Happy Coding
- Michael S
 

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

Back
Top