473,722 Members | 2,430 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Best Practise: Returning private List<> as a Property

Hi,

I feel I'm going around circles on this one and would appreciate some other
points of view.

From a design / encapsulation point of view, what's the best practise for
returning a private List<as a property.

Consider the example below, the class "ListTest" contains a private "List<>"
called "strings" - it also provides a public method to add to that list,
this method could contain all sorts of validation / modification of the
string to be added (encapsulation) . However by then exposing the private
List<as a public property you give the end user of your class the ability
to add to your List<as show below.

I understand why the above happens, I'm just trying to think what the best
course of action is if you always want your user to use the function to add
to your list, whilst retaining a property to access the list? List<>
doesn't contain a clone method - you could create this I know, but then the
amount of processing that involves implies it should be a method rather than
a parameter (parameters shouldn't really consider processor intensive code).

Like I say, I feel I'm going around in circles on this one, even to the
point of wondering if it actually matters.

Regards,

- Paul.
=============== =============== ======
using System;
using System.Collecti ons.Generic;
using System.Text;

class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddStr ing("Test 1"); // << Add the string the correct way.
Console.WriteLi ne(listTest.Str ings.Count);
listTest.String s.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteLi ne(listTest.Str ings.Count);
}
}

class ListTest
{
private List<stringstri ngs = null;

public void AddString(strin g stringToAdd)
{
if (strings == null)
strings = new List<string>();
strings.Add(str ingToAdd);
}
public List<stringStri ngs { get { return this.strings; } }
}
=============== =============== ======
Output is:
1
2
Jan 16 '07 #1
9 7899
Hi Paul,

Paul ha scritto:
[cut]

I think I haven't properly got what you need...
Antyway - taking a look to your code - the best way should be you to
create your *own* collection (implementing ICollection<T>) and
customizing the "Add" method.

HTH,
Giulio
Jan 16 '07 #2
I feel I'm going around circles on this one and would appreciate some
other points of view.

From a design / encapsulation point of view, what's the best practise
for returning a private List<as a property.

Consider the example below, the class "ListTest" contains a private
"List<>" called "strings" - it also provides a public method to add to
that list, this method could contain all sorts of validation /
modification of the string to be added (encapsulation) . However by
then exposing the private List<as a public property you give the end
user of your class the ability to add to your List<as show below.

I understand why the above happens, I'm just trying to think what the
best course of action is if you always want your user to use the
function to add to your list, whilst retaining a property to access
the list? List<doesn't contain a clone method - you could create
this I know, but then the amount of processing that involves implies
it should be a method rather than a parameter (parameters shouldn't
really consider processor intensive code).

Like I say, I feel I'm going around in circles on this one, even to
the point of wondering if it actually matters.

=============== =============== ======
using System;
using System.Collecti ons.Generic;
using System.Text;
class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddStr ing("Test 1"); // << Add the string the correct
way.
Console.WriteLi ne(listTest.Str ings.Count);
listTest.String s.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteLi ne(listTest.Str ings.Count);
}
}
class ListTest
{
private List<stringstri ngs = null;
public void AddString(strin g stringToAdd)
{
if (strings == null)
strings = new List<string>();
strings.Add(str ingToAdd);
}
public List<stringStri ngs { get { return this.strings; } }
}
=============== =============== ======
Output is:
1
2
List<should be used internally and never exposed. Once you expose it, you're
design is locked into using it. If you just need a way to iterate over the
List<from outside, you might consider making ListTest implement IEnumerable<str ing>
like this:

class ListTest: IEnumerable<str ing>
{
List<stringstri ngs = new List<string>();

public IEnumerator<str ingGetEnumerato r()
{
return strings.GetEnum erator();
}
}

Or, if you want to return the contents, you could expose a read-only indexer:

class ListTest
{
List<stringstri ngs = new List<string>();

public string this[int index] { get { return strings[index]; } }
}

Another option is to return a ReadOnlyCollect ion<string>:

class ListTest
{
List<stringstri ngs = new List<string>();

public ReadOnlyCollect ion<stringStrin gs { get { return strings.AsReadO nly();
} }
}

You might even consider doing all three. But, directly exposing the inner
bits of your class is a bad idea for lots of reasons.

Best Regards,
Dustin Campbell
Developer Express Inc.
Jan 16 '07 #3
Dustin Campbell ha scritto:
List<should be used internally and never exposed. Once you expose it,
you're design is locked into using it. If you just need a way to iterate
over the List<from outside, you might consider making ListTest
implement IEnumerable<str inglike this:
....and if you need to "manipulate " object from outside
(add/remove/clear) you should use a ICollection<T>.

My 2 cents,
Giulio - Italia

--
OnAir: Metallica - the frayed ends of sanity
Jan 16 '07 #4
Hi,

you could use the AsReadOnly method of the List<Tclass. It returns a
writeprotected wrapper around your list.

your Strings property would look like this:

public ReadOnlyCollect ion<stringStrin gs { get { return
strings.AsReadO nly() } }

The returned List will still have the Add method soice it implements IList<>
and List<>, but they will cause exceptions.
Not very nice, but atleast the caller can't change your internals.

Christof

"Paul" <no****@noone.c omschrieb im Newsbeitrag
news:OA******** ******@TK2MSFTN GP03.phx.gbl...
Hi,

I feel I'm going around circles on this one and would appreciate some
other points of view.

From a design / encapsulation point of view, what's the best practise for
returning a private List<as a property.

Consider the example below, the class "ListTest" contains a private
"List<>" called "strings" - it also provides a public method to add to
that list, this method could contain all sorts of validation /
modification of the string to be added (encapsulation) . However by then
exposing the private List<as a public property you give the end user of
your class the ability to add to your List<as show below.

I understand why the above happens, I'm just trying to think what the best
course of action is if you always want your user to use the function to
add to your list, whilst retaining a property to access the list? List<>
doesn't contain a clone method - you could create this I know, but then
the amount of processing that involves implies it should be a method
rather than a parameter (parameters shouldn't really consider processor
intensive code).

Like I say, I feel I'm going around in circles on this one, even to the
point of wondering if it actually matters.

Regards,

- Paul.
=============== =============== ======
using System;
using System.Collecti ons.Generic;
using System.Text;

class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddStr ing("Test 1"); // << Add the string the correct way.
Console.WriteLi ne(listTest.Str ings.Count);
listTest.String s.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteLi ne(listTest.Str ings.Count);
}
}

class ListTest
{
private List<stringstri ngs = null;

public void AddString(strin g stringToAdd)
{
if (strings == null)
strings = new List<string>();
strings.Add(str ingToAdd);
}
public List<stringStri ngs { get { return this.strings; } }
}
=============== =============== ======
Output is:
1
2

Jan 16 '07 #5
JS
...and if you need to "manipulate " object from outside
(add/remove/clear) you should use a ICollection<T>.
I'm just curious. Why is returning an ICollection<Tpr eferrable to
returning an IList<T?

Jan 16 '07 #6

Paul wrote:
Hi,

I feel I'm going around circles on this one and would appreciate some other
points of view.

From a design / encapsulation point of view, what's the best practise for
returning a private List<as a property.

Consider the example below, the class "ListTest" contains a private "List<>"
called "strings" - it also provides a public method to add to that list,
this method could contain all sorts of validation / modification of the
string to be added (encapsulation) . However by then exposing the private
List<as a public property you give the end user of your class the ability
to add to your List<as show below.

I understand why the above happens, I'm just trying to think what the best
course of action is if you always want your user to use the function to add
to your list, whilst retaining a property to access the list? List<>
doesn't contain a clone method - you could create this I know, but then the
amount of processing that involves implies it should be a method rather than
a parameter (parameters shouldn't really consider processor intensive code).

Like I say, I feel I'm going around in circles on this one, even to the
point of wondering if it actually matters.

Regards,

- Paul.
=============== =============== ======
using System;
using System.Collecti ons.Generic;
using System.Text;

class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddStr ing("Test 1"); // << Add the string the correct way.
Console.WriteLi ne(listTest.Str ings.Count);
listTest.String s.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteLi ne(listTest.Str ings.Count);
}
}

class ListTest
{
private List<stringstri ngs = null;

public void AddString(strin g stringToAdd)
{
if (strings == null)
strings = new List<string>();
strings.Add(str ingToAdd);
}
public List<stringStri ngs { get { return this.strings; } }
}
=============== =============== ======
Output is:
1
2
You might choose to use a custom list type. Take a look at how
ListViewItemCol lection works.

Jan 17 '07 #7
Hi JS,

JS ha scritto:
I'm just curious. Why is returning an ICollection<Tpr eferrable to
returning an IList<T?
It's just a more "restricted " interface.

Kind regards,
Giulio
Jan 17 '07 #8
Christof,

Thanks for the advice, it's a very clean solution - nice to know that I
wasn't going mad thinking there was a better way of doing things.

Also, you have to cast the returned "ReadOnlyCollec tion" property as a
"ICollection<T> " to get the Add value because it's an Explicit Interface
implementation (see below) - if you just use the property without the cast
you can't even see / use the Add method.

((ICollection<S tring>)listTest .Strings).Add(" Test 2"); // << This will throw
the exception.

Thanks again,

- Paul.

"Christof Nordiek" <cn@nospam.dewr ote in message
news:uR******** ******@TK2MSFTN GP02.phx.gbl...
Hi,

you could use the AsReadOnly method of the List<Tclass. It returns a
writeprotected wrapper around your list.

your Strings property would look like this:

public ReadOnlyCollect ion<stringStrin gs { get { return
strings.AsReadO nly() } }

The returned List will still have the Add method soice it implements
IList<and List<>, but they will cause exceptions.
Not very nice, but atleast the caller can't change your internals.

Christof

"Paul" <no****@noone.c omschrieb im Newsbeitrag
news:OA******** ******@TK2MSFTN GP03.phx.gbl...
>Hi,

I feel I'm going around circles on this one and would appreciate some
other points of view.

From a design / encapsulation point of view, what's the best practise for
returning a private List<as a property.

Consider the example below, the class "ListTest" contains a private
"List<>" called "strings" - it also provides a public method to add to
that list, this method could contain all sorts of validation /
modification of the string to be added (encapsulation) . However by then
exposing the private List<as a public property you give the end user of
your class the ability to add to your List<as show below.

I understand why the above happens, I'm just trying to think what the
best course of action is if you always want your user to use the function
to add to your list, whilst retaining a property to access the list?
List<doesn't contain a clone method - you could create this I know, but
then the amount of processing that involves implies it should be a method
rather than a parameter (parameters shouldn't really consider processor
intensive code).

Like I say, I feel I'm going around in circles on this one, even to the
point of wondering if it actually matters.

Regards,

- Paul.
============== =============== =======
using System;
using System.Collecti ons.Generic;
using System.Text;

class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddStr ing("Test 1"); // << Add the string the correct
way.
Console.WriteLi ne(listTest.Str ings.Count);
listTest.String s.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteLi ne(listTest.Str ings.Count);
}
}

class ListTest
{
private List<stringstri ngs = null;

public void AddString(strin g stringToAdd)
{
if (strings == null)
strings = new List<string>();
strings.Add(str ingToAdd);
}
public List<stringStri ngs { get { return this.strings; } }
}
============== =============== =======
Output is:
1
2


Jan 17 '07 #9
Thanks Dustin,

That's really helpful - I've gone with the ReadOnlyCollect ion option as it
does exactly what I wanted - sometimes I do want to return the whole
collection, not just iterate over it or return specific elements.

Regards,

- Paul.
"Dustin Campbell" <du*****@no-spam-pleasedevexpres s.comwrote in message
news:c1******** *************** ***@news.micros oft.com...
>I feel I'm going around circles on this one and would appreciate some
other points of view.

From a design / encapsulation point of view, what's the best practise
for returning a private List<as a property.

Consider the example below, the class "ListTest" contains a private
"List<>" called "strings" - it also provides a public method to add to
that list, this method could contain all sorts of validation /
modification of the string to be added (encapsulation) . However by
then exposing the private List<as a public property you give the end
user of your class the ability to add to your List<as show below.

I understand why the above happens, I'm just trying to think what the
best course of action is if you always want your user to use the
function to add to your list, whilst retaining a property to access
the list? List<doesn't contain a clone method - you could create
this I know, but then the amount of processing that involves implies
it should be a method rather than a parameter (parameters shouldn't
really consider processor intensive code).

Like I say, I feel I'm going around in circles on this one, even to
the point of wondering if it actually matters.

============== =============== =======
using System;
using System.Collecti ons.Generic;
using System.Text;
class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddSt ring("Test 1"); // << Add the string the correct
way.
Console.WriteL ine(listTest.St rings.Count);
listTest.Strin gs.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteL ine(listTest.St rings.Count);
}
}
class ListTest
{
private List<stringstri ngs = null;
public void AddString(strin g stringToAdd)
{
if (strings == null)
strings = new List<string>();
strings.Add(st ringToAdd);
}
public List<stringStri ngs { get { return this.strings; } }
}
============== =============== =======
Output is:
1
2

List<should be used internally and never exposed. Once you expose it,
you're design is locked into using it. If you just need a way to iterate
over the List<from outside, you might consider making ListTest implement
IEnumerable<str inglike this:

class ListTest: IEnumerable<str ing>
{
List<stringstri ngs = new List<string>();

public IEnumerator<str ingGetEnumerato r()
{
return strings.GetEnum erator();
}
}

Or, if you want to return the contents, you could expose a read-only
indexer:

class ListTest
{
List<stringstri ngs = new List<string>();

public string this[int index] { get { return strings[index]; } }
}

Another option is to return a ReadOnlyCollect ion<string>:

class ListTest
{
List<stringstri ngs = new List<string>();

public ReadOnlyCollect ion<stringStrin gs { get { return
strings.AsReadO nly(); } }
}

You might even consider doing all three. But, directly exposing the inner
bits of your class is a bad idea for lots of reasons.

Best Regards,
Dustin Campbell
Developer Express Inc.


Jan 17 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
52985
by: matty.hall | last post by:
I have two classes: a base class (BaseClass) and a class deriving from it (DerivedClass). I have a List<DerivedClass> that for various reasons needs to be of that type, and not a List<BaseClass>. However, I need to cast that list to a List<BaseClass> and it is not working. The code is below. I get the following exception: "Unable to cast object of type 'System.Collections.Generic.List`1' to type 'System.Collections.Generic.List`1'." ...
6
13915
by: Jeff.Boeker | last post by:
I'm learning a lesson in how I need to be more specific :) In C++ I can resize a vector and it will allocate memory and it will call the default constructor if necessary (or I can supply an instance for the copy constructor). For example: C++ vector<classvClass;
7
57554
by: Andrew Robinson | last post by:
I have a method that needs to return either a Dictionary<k,vor a List<v> depending on input parameters and options to the method. 1. Is there any way to convert from a dictionary to a list without itterating through the entire collection and building up a list? 2. is there a common base class, collection or interface that can contain either/both of these collection types and then how do you convert or cast from the base to either a...
56
5191
by: Zytan | last post by:
Obviously you can't just use a simple for loop, since you may skip over elements. You could modify the loop counter each time an element is deleted. But, the loop ending condition must be checked on each iteration, since the Count changes as you delete elements. I would think it is guaranteed to be computed each time, and not cached. So, is this the best way?
45
18882
by: Zytan | last post by:
This returns the following error: "Cannot modify the return value of 'System.Collections.Generic.List<MyStruct>.this' because it is not a variable" and I have no idea why! Do lists return copies of their elements? Why can't I change the element itself? class Program { private struct MyStruct
0
8863
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8739
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9384
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9088
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6681
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5995
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4502
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4762
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2147
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.