471,599 Members | 1,819 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,599 software developers and data experts.

How to create a generic readonly collection?

I know I can use ArrayList.ReadOnly() to create a readonly version of it,
but how can I achive a similar thing with a generic collection of .NET 2.0?
Nov 17 '05 #1
5 3003


cody wrote:
I know I can use ArrayList.ReadOnly() to create a readonly version of it,
but how can I achive a similar thing with a generic collection of .NET 2.0?


Implement a proxy for the relevant collection, which throw's on mutation.

Here is an example on the .NET1.1 IDictionary, I haven't changed to
..NET2 yet -- you should be able to write one for IDictionary<> in .NET2
yourself.

using System.Collections;

class Immutable: Exception
{ public Immutable(): base("Attempt to change immutable object") {} }

/// <summary>
/// Provide immutable access to a dictionary.
/// </summary>
/// <remarks>
/// In JAVA, iterators, as well as the key- and value- parts, of a
dictionary
/// (called Map) allows mutation, so in JAVA a much more elaborate proxying
/// is required.
/// </remarks>
class ImmutableIDictionary: IDictionary
{
protected readonly IDictionary proxied;
public ImmutableIDictionary(IDictionary proxied) {
if ( proxied == null )
throw new ArgumentException(
"Cannot proxy uninstantiated IDictionary", "proxied");
this.proxied = proxied;
}
#region IDictionary Members
public bool IsReadOnly { get { return true; } }
public IDictionaryEnumerator GetEnumerator()
{ return proxied.GetEnumerator(); }
public object this[object key]
{ get { return proxied[key]; } set { throw new Immutable(); } }
public void Remove(object key) { throw new Immutable(); }
public bool Contains(object key) { return proxied.Contains(key); }
public void Clear() { throw new Immutable(); }
public ICollection Values { get { return proxied.Values; } }
public void Add(object key, object value) { throw new Immutable(); }
public ICollection Keys { get { return proxied.Keys; } }
public bool IsFixedSize { get { return true; } }
#endregion

#region ICollection Members
public bool IsSynchronized { get { return proxied.IsSynchronized; } }
public int Count { get { return proxied.Count; } }
public void CopyTo(Array array, int index) { proxied.CopyTo(array,
index); }
public object SyncRoot { get { return proxied.SyncRoot; } }
#endregion

#region IEnumerable Members
IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
IEnumerable e = proxied;
return e.GetEnumerator();
}
#endregion
}

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #2
Thanks for the answer.

So that means there is no predefined method for getting a readonly List<> in
..NET 2.0?

This is very bad. Since .NET lacks the const modifier like in C++ there
should at least be a simple solution for that without having to write
readonly wrappers for all collection classes all the time by myself :(

"Helge Jensen" <he**********@slog.dk> schrieb im Newsbeitrag
news:#l**************@TK2MSFTNGP12.phx.gbl...


cody wrote:
I know I can use ArrayList.ReadOnly() to create a readonly version of it, but how can I achive a similar thing with a generic collection of .NET
2.0?
Implement a proxy for the relevant collection, which throw's on mutation.

Here is an example on the .NET1.1 IDictionary, I haven't changed to
.NET2 yet -- you should be able to write one for IDictionary<> in .NET2
yourself.

using System.Collections;

class Immutable: Exception
{ public Immutable(): base("Attempt to change immutable object") {} }

/// <summary>
/// Provide immutable access to a dictionary.
/// </summary>
/// <remarks>
/// In JAVA, iterators, as well as the key- and value- parts, of a
dictionary
/// (called Map) allows mutation, so in JAVA a much more elaborate proxying /// is required.
/// </remarks>
class ImmutableIDictionary: IDictionary
{
protected readonly IDictionary proxied;
public ImmutableIDictionary(IDictionary proxied) {
if ( proxied == null )
throw new ArgumentException(
"Cannot proxy uninstantiated IDictionary", "proxied");
this.proxied = proxied;
}
#region IDictionary Members
public bool IsReadOnly { get { return true; } }
public IDictionaryEnumerator GetEnumerator()
{ return proxied.GetEnumerator(); }
public object this[object key]
{ get { return proxied[key]; } set { throw new Immutable(); } }
public void Remove(object key) { throw new Immutable(); }
public bool Contains(object key) { return proxied.Contains(key); }
public void Clear() { throw new Immutable(); }
public ICollection Values { get { return proxied.Values; } }
public void Add(object key, object value) { throw new Immutable(); }
public ICollection Keys { get { return proxied.Keys; } }
public bool IsFixedSize { get { return true; } }
#endregion

#region ICollection Members
public bool IsSynchronized { get { return proxied.IsSynchronized; } }
public int Count { get { return proxied.Count; } }
public void CopyTo(Array array, int index) { proxied.CopyTo(array,
index); }
public object SyncRoot { get { return proxied.SyncRoot; } }
#endregion

#region IEnumerable Members
IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
IEnumerable e = proxied;
return e.GetEnumerator();
}
#endregion
}

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-

Nov 17 '05 #3


Matthias Schack wrote:
Thanks for the answer.

So that means there is no predefined method for getting a readonly List<> in
.NET 2.0?
I am not qualified to answer that, since I haven't used 2.0 yet, *but*
since .NET1.1 doesn't have it, and I haven't read about it being
introduced in .NET2, and since you asked (I suppose you've looked in the
docs), there quite possibly aren't any.
This is very bad. Since .NET lacks the const modifier like in C++ there
should at least be a simple solution for that without having to write
readonly wrappers for all collection classes all the time by myself :(


Aaaah, lots of things are far worse, besides const comes with just about
as many problems as it solves (hence the discussion about whether it's
good or bad).

Really, ICollection does not provide mutation, that leaves IList and
IDictionary from .NET1.1 and (to my poor knowledge) IList<>,
IDictionary<> and ISet<> from .NET2. All in all 5 classes.

Just be glad you're not in JAVA, where writing a readonly proxy is much
more complicated.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #4
List.AsReadOnly retuns a read-only wrapper arround the current List.
Willy.

"Matthias Schack" <Sc***********@gmx.de> wrote in message
news:uJ*************@TK2MSFTNGP10.phx.gbl...
Thanks for the answer.

So that means there is no predefined method for getting a readonly List<>
in
.NET 2.0?

This is very bad. Since .NET lacks the const modifier like in C++ there
should at least be a simple solution for that without having to write
readonly wrappers for all collection classes all the time by myself :(

"Helge Jensen" <he**********@slog.dk> schrieb im Newsbeitrag
news:#l**************@TK2MSFTNGP12.phx.gbl...


cody wrote:
> I know I can use ArrayList.ReadOnly() to create a readonly version of it, > but how can I achive a similar thing with a generic collection of .NET

2.0?

Implement a proxy for the relevant collection, which throw's on mutation.

Here is an example on the .NET1.1 IDictionary, I haven't changed to
.NET2 yet -- you should be able to write one for IDictionary<> in .NET2
yourself.

using System.Collections;

class Immutable: Exception
{ public Immutable(): base("Attempt to change immutable object") {} }

/// <summary>
/// Provide immutable access to a dictionary.
/// </summary>
/// <remarks>
/// In JAVA, iterators, as well as the key- and value- parts, of a
dictionary
/// (called Map) allows mutation, so in JAVA a much more elaborate

proxying
/// is required.
/// </remarks>
class ImmutableIDictionary: IDictionary
{
protected readonly IDictionary proxied;
public ImmutableIDictionary(IDictionary proxied) {
if ( proxied == null )
throw new ArgumentException(
"Cannot proxy uninstantiated IDictionary", "proxied");
this.proxied = proxied;
}
#region IDictionary Members
public bool IsReadOnly { get { return true; } }
public IDictionaryEnumerator GetEnumerator()
{ return proxied.GetEnumerator(); }
public object this[object key]
{ get { return proxied[key]; } set { throw new Immutable(); } }
public void Remove(object key) { throw new Immutable(); }
public bool Contains(object key) { return proxied.Contains(key); }
public void Clear() { throw new Immutable(); }
public ICollection Values { get { return proxied.Values; } }
public void Add(object key, object value) { throw new Immutable(); }
public ICollection Keys { get { return proxied.Keys; } }
public bool IsFixedSize { get { return true; } }
#endregion

#region ICollection Members
public bool IsSynchronized { get { return proxied.IsSynchronized; } }
public int Count { get { return proxied.Count; } }
public void CopyTo(Array array, int index) { proxied.CopyTo(array,
index); }
public object SyncRoot { get { return proxied.SyncRoot; } }
#endregion

#region IEnumerable Members
IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
IEnumerable e = proxied;
return e.GetEnumerator();
}
#endregion
}

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-


Nov 17 '05 #5
Thank you that was what I was looking for.
"Willy Denoyette [MVP]" <wi*************@telenet.be> schrieb im Newsbeitrag
news:OP**************@TK2MSFTNGP12.phx.gbl...
List.AsReadOnly retuns a read-only wrapper arround the current List.
Willy.

"Matthias Schack" <Sc***********@gmx.de> wrote in message
news:uJ*************@TK2MSFTNGP10.phx.gbl...
Thanks for the answer.

So that means there is no predefined method for getting a readonly List<>
in
.NET 2.0?

This is very bad. Since .NET lacks the const modifier like in C++ there
should at least be a simple solution for that without having to write
readonly wrappers for all collection classes all the time by myself :(

"Helge Jensen" <he**********@slog.dk> schrieb im Newsbeitrag
news:#l**************@TK2MSFTNGP12.phx.gbl...


cody wrote:
> I know I can use ArrayList.ReadOnly() to create a readonly version of

it,
> but how can I achive a similar thing with a generic collection of .NET

2.0?

Implement a proxy for the relevant collection, which throw's on
mutation.

Here is an example on the .NET1.1 IDictionary, I haven't changed to
.NET2 yet -- you should be able to write one for IDictionary<> in .NET2
yourself.

using System.Collections;

class Immutable: Exception
{ public Immutable(): base("Attempt to change immutable object") {} }

/// <summary>
/// Provide immutable access to a dictionary.
/// </summary>
/// <remarks>
/// In JAVA, iterators, as well as the key- and value- parts, of a
dictionary
/// (called Map) allows mutation, so in JAVA a much more elaborate

proxying
/// is required.
/// </remarks>
class ImmutableIDictionary: IDictionary
{
protected readonly IDictionary proxied;
public ImmutableIDictionary(IDictionary proxied) {
if ( proxied == null )
throw new ArgumentException(
"Cannot proxy uninstantiated IDictionary", "proxied");
this.proxied = proxied;
}
#region IDictionary Members
public bool IsReadOnly { get { return true; } }
public IDictionaryEnumerator GetEnumerator()
{ return proxied.GetEnumerator(); }
public object this[object key]
{ get { return proxied[key]; } set { throw new Immutable(); } }
public void Remove(object key) { throw new Immutable(); }
public bool Contains(object key) { return proxied.Contains(key); }
public void Clear() { throw new Immutable(); }
public ICollection Values { get { return proxied.Values; } }
public void Add(object key, object value) { throw new Immutable(); }
public ICollection Keys { get { return proxied.Keys; } }
public bool IsFixedSize { get { return true; } }
#endregion

#region ICollection Members
public bool IsSynchronized { get { return proxied.IsSynchronized; } }
public int Count { get { return proxied.Count; } }
public void CopyTo(Array array, int index) { proxied.CopyTo(array,
index); }
public object SyncRoot { get { return proxied.SyncRoot; } }
#endregion

#region IEnumerable Members
IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
IEnumerable e = proxied;
return e.GetEnumerator();
}
#endregion
}

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-



Nov 17 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

7 posts views Thread by Paul Welter | last post: by
8 posts views Thread by JAL | last post: by
22 posts views Thread by Adam Clauss | last post: by
4 posts views Thread by Adam Clauss | last post: by
19 posts views Thread by Brett Romero | last post: by
7 posts views Thread by Sehboo | last post: by
3 posts views Thread by dgk | last post: by
reply views Thread by Anwar ali | last post: by

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.