How about this property:
public static IEnumerable<KeyValuePair<string, object> CacheItems
{
get
{
return cacheItems;
}
}
The Dictionary implements the IEnumerable interface (which will already used by your foreach statement), but by only exposing it really as a IEnumerable you prevent any possibility to add or remove items to the dictionary.
If you need to access the dictionary by the index operator you can quite easily implement a ReadOnlyDictionary. It would then look something like this:
public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private IDictionary<TKey, TValue> _Source;
public ReadOnlyDictionary(IDictionary<TKey, TValue> source)
{
if(source == null)
throw new ArgumentNullException("source");
_Source = source;
}
// ToDo: Implement all methods of IDictionary and simply forward
// anything to the _Source, except the Add, Remove, etc. methods
// will directly throw an NotSupportedException.
}
In that case you could then also propagate your cache as
private static ReadOnlyDictionary<string, object> _CacheReadOnly;
private static Dictionary<string, object> _CacheItems;
public static ctor()
{
_CacheItems = new Dictionary<string, object>();
_CacheReadOnly = new ReadOnlyDictionary(_CacheItems);
}
public static IDictionary<string, object> CacheItems
{
get
{
return CacheReadOnly;
}
}
Update
If you really need to prevent the cast back to Dictionary you could also use this:
public static IEnumerable<KeyValuePair<string, object> CacheItems
{
get
{
return cacheItems.Select(x => x);
}
}