471,355 Members | 1,618 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

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

Read-Only Hashtable - how?

Hashtable has a property IsReadOnly. i can't figure out how this gets set.
It's not a property you can set directly and i can't find a constructor that
takes an RO parameter. How on earth does it get set?

More generally, is there a way i can expose a stanadrd collection as
read-only? Manager should be able to load and modify Employees internally but
when exposing it to the caller it should not let the caller change it.

i can do this by writing my own custom class (and maybe inheriting
ReadOnlyCollectionBase) but i'd rather use a built in class if one is
available

i considered keeping a normal Hashtable (or somesuch) internally and
re-casting it or cloning it to something readonly to expose but didn't find
anything suitable

i thought for a second i could add the keyword readonly in front of the
variable declaration but i have since learned the error of my ways

So is there a way to use one of the built-in collections to expose read-only
data or do i need to create my own?

-baylor
Jul 21 '05 #1
1 2906
baylor wrote:
Hashtable has a property IsReadOnly. i can't figure out how this gets set. i can do this by writing my own custom class (and maybe inheriting
ReadOnlyCollectionBase) but i'd rather use a built in class if one is
available
You will need to proxy the collection.
Note that you need to trust the caller not to downcast the Values, Keys,
GetEnumerator(), ... if you don't want to proxy those.

Below is some exaple code you can use as:

IDictionary dict = some_dictionary_which_may_be_read_write;
return ReadOnlyDictionary.Make(dict);
class ReadOnlyDictionary: IDictionary
{
public static IDictionary Make(IDictionary dict)
{
if ( dict.IsReadOnly )
return dict;
else
return new ReadOnlyDictionary(dict);
}
class Immutable: NotSupportedException
{ public Immutable(): base("Immutable data-structure") {} }
protected IDictionary Parent;
protected ReadOnlyDictionary(IDictionary dict)
{ this.Parent = dict; }
#region IDictionary Members
public bool IsReadOnly { get { return true; } }
/* IDictionaryEnumerator doesn't provide mutation
so we can reuse parents without proxy
if we trust the caller not to downcast
to the real type
*/
public IDictionaryEnumerator GetEnumerator()
{ return Parent.GetEnumerator(); }
public object this[object key]
{
get { return Parent[key]; }
set { throw new Immutable(); }
}
public void Remove(object key) { throw new Immutable(); }
public bool Contains(object key) { return Parent.Contains(key); }
public void Clear() { throw new Immutable(); }
/* ICollection doesn't provide mutation
so we can reuse parents without proxy
if we trust the caller not to downcast
to the real type
*/
public ICollection Values { get { return Parent.Values; } }
public void Add(object key, object value) { throw new Immutable(); }
/* ICollection doesn't provide mutation
so we can reuse parents without proxy
if we trust the caller not to downcast
to the real type
*/
public ICollection Keys { get { return Parent.Keys; } }
public bool IsFixedSize { get { return Parent.IsFixedSize; } }
#endregion

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

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

public override bool Equals(object obj)
{ return Parent.Equals(obj); }
public override int GetHashCode() { return Parent.GetHashCode(); }
public override string ToString() { return Parent.ToString(); }
}
So is there a way to use one of the built-in collections to expose read-only
data or do i need to create my own?


Just use a proxy, it's rather convinient.

Remember, that this doesn't guard you against people using reflection or
whatnot. The only alternative is to copy your returned hashtable's, that
way you don't *care* if the caller edits it.

return new Hashtable(dict);

But that's awfully expensive.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Jul 21 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Gunnar | last post: by
6 posts views Thread by Steve | last post: by
12 posts views Thread by Steven T. Hatton | last post: by
2 posts views Thread by Sandman | last post: by
4 posts views Thread by Ollie Cook | last post: by
1 post views Thread by Jose Reckoner | last post: by
6 posts views Thread by arnuld | last post: by
4 posts views Thread by zl2k | last post: by
5 posts views Thread by Thomas Christensen | last post: by
reply views Thread by XIAOLAOHU | 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.