By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,030 Members | 1,997 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,030 IT Pros & Developers. It's quick & easy.

Best Practise: Returning private List<> as a Property

P: n/a
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.Collections.Generic;
using System.Text;

class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddString("Test 1"); // << Add the string the correct way.
Console.WriteLine(listTest.Strings.Count);
listTest.Strings.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteLine(listTest.Strings.Count);
}
}

class ListTest
{
private List<stringstrings = null;

public void AddString(string stringToAdd)
{
if (strings == null)
strings = new List<string>();
strings.Add(stringToAdd);
}
public List<stringStrings { get { return this.strings; } }
}
====================================
Output is:
1
2
Jan 16 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
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

P: n/a
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.Collections.Generic;
using System.Text;
class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddString("Test 1"); // << Add the string the correct
way.
Console.WriteLine(listTest.Strings.Count);
listTest.Strings.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteLine(listTest.Strings.Count);
}
}
class ListTest
{
private List<stringstrings = null;
public void AddString(string stringToAdd)
{
if (strings == null)
strings = new List<string>();
strings.Add(stringToAdd);
}
public List<stringStrings { 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<string>
like this:

class ListTest: IEnumerable<string>
{
List<stringstrings = new List<string>();

public IEnumerator<stringGetEnumerator()
{
return strings.GetEnumerator();
}
}

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

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

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

Another option is to return a ReadOnlyCollection<string>:

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

public ReadOnlyCollection<stringStrings { get { return strings.AsReadOnly();
} }
}

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

P: n/a
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<stringlike 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

P: n/a
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 ReadOnlyCollection<stringStrings { get { return
strings.AsReadOnly() } }

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.comschrieb im Newsbeitrag
news:OA**************@TK2MSFTNGP03.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.Collections.Generic;
using System.Text;

class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddString("Test 1"); // << Add the string the correct way.
Console.WriteLine(listTest.Strings.Count);
listTest.Strings.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteLine(listTest.Strings.Count);
}
}

class ListTest
{
private List<stringstrings = null;

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

Jan 16 '07 #5

P: n/a
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<Tpreferrable to
returning an IList<T?

Jan 16 '07 #6

P: n/a

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.Collections.Generic;
using System.Text;

class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddString("Test 1"); // << Add the string the correct way.
Console.WriteLine(listTest.Strings.Count);
listTest.Strings.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteLine(listTest.Strings.Count);
}
}

class ListTest
{
private List<stringstrings = null;

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

Jan 17 '07 #7

P: n/a
Hi JS,

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

Kind regards,
Giulio
Jan 17 '07 #8

P: n/a
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 "ReadOnlyCollection" 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<String>)listTest.Strings).Add("Test 2"); // << This will throw
the exception.

Thanks again,

- Paul.

"Christof Nordiek" <cn@nospam.dewrote in message
news:uR**************@TK2MSFTNGP02.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 ReadOnlyCollection<stringStrings { get { return
strings.AsReadOnly() } }

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.comschrieb im Newsbeitrag
news:OA**************@TK2MSFTNGP03.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.Collections.Generic;
using System.Text;

class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddString("Test 1"); // << Add the string the correct
way.
Console.WriteLine(listTest.Strings.Count);
listTest.Strings.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteLine(listTest.Strings.Count);
}
}

class ListTest
{
private List<stringstrings = null;

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


Jan 17 '07 #9

P: n/a
Thanks Dustin,

That's really helpful - I've gone with the ReadOnlyCollection 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-pleasedevexpress.comwrote in message
news:c1**************************@news.microsoft.c om...
>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.Collections.Generic;
using System.Text;
class Program
{
static void Main(string[] args)
{
ListTest listTest = new ListTest();
listTest.AddString("Test 1"); // << Add the string the correct
way.
Console.WriteLine(listTest.Strings.Count);
listTest.Strings.Add("Test 2"); // << by-pass the AddString()
function.
Console.WriteLine(listTest.Strings.Count);
}
}
class ListTest
{
private List<stringstrings = null;
public void AddString(string stringToAdd)
{
if (strings == null)
strings = new List<string>();
strings.Add(stringToAdd);
}
public List<stringStrings { 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<stringlike this:

class ListTest: IEnumerable<string>
{
List<stringstrings = new List<string>();

public IEnumerator<stringGetEnumerator()
{
return strings.GetEnumerator();
}
}

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

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

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

Another option is to return a ReadOnlyCollection<string>:

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

public ReadOnlyCollection<stringStrings { get { return
strings.AsReadOnly(); } }
}

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 discussion thread is closed

Replies have been disabled for this discussion.