There is little difference between a public static readonly field and a public static property. The property does protect access to some extent, but if all you're doing is returning the value, the two don't really differ.
// access between these two is almost identical
public class Foo
{
public readonly static IDictionary<string, int> bar =
new Dictionary<string, int>();
public static IDictionary<string, int> Bar
{
get { return bar; }
}
}
The issue you are going to run into is that even though the field has been marked as readonly
it is still mutable. What's to stop someone from calling Foo.Bar.Clear();
In order to resolve this, you could create a copy and return that, or you could find use a readonly dictionary implementation.
public class Foo
{
private readonly static IDictionary<string, int> bar =
new Dictionary<string, int>();
public static IDictionary<string, int> Bar
{
// now any calls like Foo.Bar.Clear(); will not clear Foo.bar
get { return new Dictionary<string, int>(bar); }
}
}
Then if you if you do need to add or remove items from Foo.Bar
you can create functions to limit how the underlying object is modified.
public static void AddItem(string key, int value)
{ }
public static void RemoveItem(string key)
{ }
Even if you use a ReadonlyDictionary
implementation, you may still run into issues with modification, if the TKey
or TValue
of the dictionary are mutable.
Overall those, the reasons you've seen to avoid the public static variables still hold true here. You are introducing a static dependency that will be dragged along whenever the code that uses Foo.Bar
is reused. Unless the object you are statically accessing is immutable as well as readonly, there are any number of unforeseen side effects that may occur.
You would be better off creating single instance of the object at your composition root and passing that around to the objects that need the dependency.
public void CompRoot()
{
var bar = new ReadonlyDictionary(
... initialize with desired values ...
// also this object is not in .NET but there
// are many available on the net
);
var obj = new UsesBarDependency(bar);
}
public class UsesBarDependency
{
private readonly ReadonlyDictionary bar;
public UsesBarDependency(ReadonlyDictionary bar)
{
if (bar == null)
throw new ArgumentNullException("bar");
this.bar = bar;
}
public void Func()
{
// use to access the dependency
this.bar
// over
Foo.Bar
}
}
Doing so allows users of UsesBarDependency
to provide whatever ReadonlyDictionary
to the object instead of being forced to use the static Foo.Bar
dependency.