[C++/C#] Coding advices

Started by
8 comments, last by johnnie to 14 years, 1 month ago
Hi guys, I've started study c# a few days ago and I'm wondering what's the best practice (general) when you have something like this:


class MyClass
{
   List<AnotherCustomClass> MyList { get; set; }
}

As far as I know, what happen is that the compiler replace the set property with something like


public setMyList(List<AnotherCustomClass> anotherList)
{
   MyList = anotherList;
}

just copying the reference. In a scenario like this MyList and anotherList point to the same object so, inside MyClass, I'm going to modify an external object and, as far as I know, this isn't a good practice. Do I need to implement IClonable interface for my types and make a deep copy when I encounter situation like the one I showed above? Thank you, johnnie
Advertisement
It's up to you whether you use references or deep copies. I tend to almost always use references and only deep copy if I absolutely need to, but that's just the way I do things.
Quote:Original post by johnnie to
In a scenario like this MyList and anotherList point to the same object so, inside MyClass, I'm going to modify an external object and, as far as I know, this isn't a good practice.


It is perfectly fine, as that is the expected behavior of the language mechanics. However, if it is not what you intended, you certainly should not allow it. But at that point, you might want to reconsider exposing the list as a public property, as you are going to reimplement the property with potentially unexpected behavior for the user.
Why do you need to expose the set accessor publicly on your List?

Initialise the list in your constructor. Then you can simply do the following:

MyClass class = new MyClass(...);class.MyList.Add(...);/// Etc...
Thank you all for the answers!
This doubt has arisen when I've read (somewhere) that *usually* isn't a good practice to modify the state of an object you pass as a parameter to a function.
That's make perfect sense in some cases so I was looking for a more general rule, if any :)

Sorry for my english (not a native english speaker) and may ultra-beginner questions.



johnnie
Quote:Original post by adt7
Why do you need to expose the set accessor publicly on your List?

Initialise the list in your constructor. Then you can simply do the following:

*** Source Snippet Removed ***


Well, it's because I need (or give the user the power to) modify that list... still dont know if it's absolutely needed, thanx for the question, I'll think about it.



They can still modify the contents of the list by only exposing get. They simply lose the ability to to do class.MyList = new List<>() or class.MyList = list;.
If you use a property to assign a list to a property member then it looks like a simple shallow assignment - it doesn't have to be a shallow copy, because properties can do anything, but if it's not then things start to seem complex.

Alternatively, if you want different semantics, you can use a method whose name indicates the intention in some way. Internally the class might wish to cache and modify the list, so the function makes a deep copy in order to avoid unexpected side-effects.

At the end of the day you have to decide on the semantics of your classes and their methods, using properties goes someway towards stating your intention in code. If the class maintains and mutates a shallow copy of the list then users need to be made aware of this: properties can hint at it, appropriately descriptive class/method names make it clearer and documentation defines it no uncertain terms.

Mutating a shallow copy of a user-provided instance when the semantics don't call for it is a sign that you're leaking implementation details. Of course, you might have to trade that off against the efficiency of making deep copies everywhere. In those cases I tend to find that it's usually possible to modify the semantics of a class to make shallow copies the natural choice; the use of immutable data structures can help in this regard too.
Quote:Original post by adt7
They can still modify the contents of the list by only exposing get. They simply lose the ability to to do class.MyList = new List<>() or class.MyList = list;.


That's right, still the user has the total control of what he's going to modify or not and he can track down these changes. On the other side, if a function modify the state of an object you pass as a parameter then the user may not be aware of this change... that's where the the return value kicks in.
Quote:Original post by dmatter


Nice explanation, dmatter. Many thanx ;)

This topic is closed to new replies.

Advertisement