Method or property?

A

Allan Ebdrup

I have a dictionary that I would like to load with data and then have as
read only, so I can pass it as a result of a get on a property and not have
the recipient of the dictionary change the data in it (and change the data
for everyone else using the property).
I can see from:
http://msdn.microsoft.com/library/d...nref/html/cpconconstructorusageguidelines.asp
that you should use a method when:
"The member returns an array. Properties that return arrays can be very
misleading. Usually it is necessary to return a copy of the internal array
so that the user cannot change internal state."

But I don't want to have to copy my dictionary, I just don't want the reader
of the dictionary to be able to change the data in it.

What's the best solution?
 
J

Joel Hendrix [MSFT]

You could create your own custom dictionary class that is read-only.
Something like the following:

class ReadOnlyDictionary : DictionaryBase
{
public ReadOnlyDictionary ()
{
// populate dictionary here
}

public object this[string key]
{
get
{
return this.Dictionary[key];
}
}

// override other methods you require
}

You can then expose this dictionary via a property in you containing class:

class Container
{
ReadOnlyDictionary myStuff; // initialized in ctor

... other Container stuff

public ReadOnlyDictionary Stuff
{
get
{
return this.myStuff;
}
}
}

This will provide consumers of Container read-only access both to the
dictionary and its contents.

hth

-Joel
--------------------
From: "Allan Ebdrup" <[email protected]>
Subject: Method or property?
Date: Tue, 26 Apr 2005 16:31:53 +0200
Lines: 17
Organization: OFiR
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.2527
X-RFC2646: Format=Flowed; Original
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2527
Message-ID: <#[email protected]>
Newsgroups: microsoft.public.dotnet.languages.csharp
NNTP-Posting-Host: 193.0.243.15
Path: TK2MSFTNGXA01.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP10.phx.gbl
Xref: TK2MSFTNGXA01.phx.gbl microsoft.public.dotnet.languages.csharp:94320
X-Tomcat-NG: microsoft.public.dotnet.languages.csharp

I have a dictionary that I would like to load with data and then have as
read only, so I can pass it as a result of a get on a property and not have
the recipient of the dictionary change the data in it (and change the data
for everyone else using the property).
I can see from:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/h tml/cpconconstructorusageguidelines.asp
that you should use a method when:
"The member returns an array. Properties that return arrays can be very
misleading. Usually it is necessary to return a copy of the internal array
so that the user cannot change internal state."

But I don't want to have to copy my dictionary, I just don't want the reader
of the dictionary to be able to change the data in it.

What's the best solution?

This reply is provided AS IS, without warranty (express or implied).
 
A

Allan Ebdrup

Joel Hendrix said:
You could create your own custom dictionary class that is read-only.

Yes I thought that making a dictionary where you can only write to it in the
constructor might solve the problem.
Wouldn't it be possible to make an internal class that can only be populated
from the parent class but can be lokkup'ed from all other classes?

Kind Regards,
Allan Ebdrup
 
J

Joel Hendrix [MSFT]

Yeah, that would be a better approach (which I actually implemented today
for one of my projects). Last night on my way home I realized that there
is a flaw in my original suggestion. Consider this code fragment building
on my previous example, assuming that the ctor for the ReadOnlyDictionary
class takes a key and a value as arguments.

ReadOnlyDictionary readonly = new ReadOnlyDictionary("key", "value");
Console.WriteLine(readonly["key"]);

// oops, now it's not readonly
IDictionary id = (IDictionary)readonly;
id["key"] = "new value";

Console.WriteLine(readonly["key"]);

I ended up implementing something like this:

class ReadOnlyDictionary : IEnumerable
{
private StringDictionary dictionary;

public ReadOnlyDictionary(<args to populate the dictionary>)
{
this.dictionary = new StringDictionary();
// populate dictionary
}

public string this[string key] { get { return this.dictionary[key] } }

public IEnumerator GetEnumerator()
{
return this.dictionary.GetEnumerator();
}
}

hth

-Joel
--------------------
From: "Allan Ebdrup" <[email protected]>
References: <#[email protected]>
Subject: Re: Method or property?
Date: Wed, 27 Apr 2005 10:42:15 +0200
Lines: 13
Organization: OFiR
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.2527
X-RFC2646: Format=Flowed; Original
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2527
Message-ID: <[email protected]>
Newsgroups: microsoft.public.dotnet.languages.csharp
NNTP-Posting-Host: 193.0.243.15
Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGXA03.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP1
4.phx.gbl
Xref: TK2MSFTNGXA02.phx.gbl microsoft.public.dotnet.languages.csharp:323334
X-Tomcat-NG: microsoft.public.dotnet.languages.csharp



Yes I thought that making a dictionary where you can only write to it in the
constructor might solve the problem.
Wouldn't it be possible to make an internal class that can only be populated
from the parent class but can be lokkup'ed from all other classes?

Kind Regards,
Allan Ebdrup

This reply is provided AS IS, without warranty (express or implied).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top