ConcurrentDictionary.GetOrAdd(TKey, Func<TKey, TValue>) accepts a factory function to allow lazy instantiation of the item to be put into the dictionary.
Is it safe to define a factory function that itself calls GetOrAdd(), i.e. GetOrAdd is being called within the context of a 'parent' GetOrAdd().
The following code demonstrates the pattern; It does appear to work, but is it safe?
class Program
{
static ConcurrentDictionary<string,object> __dict = new ConcurrentDictionary<string, object>();
static void Main(string[] args)
{
Foo foo = GetOrAddFoo();
Console.WriteLine(foo._name);
Console.WriteLine(foo._bar._name);
Console.ReadKey();
}
static Bar GetOrAddBar()
{
Console.WriteLine("GetOrAddBar: enter");
Func<string,Bar> factoryFn = (x) => LoadBar(x);
Bar bar = __dict.GetOrAdd("bar", factoryFn) as Bar;
Console.WriteLine("GetOrAddBar: exit");
return bar;
}
static Foo GetOrAddFoo()
{
Console.WriteLine("GetOrAddFoo: enter");
Func<string,Foo> factoryFn = (x) => LoadFoo(x);
Foo foo = __dict.GetOrAdd("foo", factoryFn) as Foo;
Console.WriteLine("GetOrAddFoo: exit");
return foo;
}
static Bar LoadBar(string name)
{
Bar bar = new Bar();
bar._name = name;
return bar;
}
static Foo LoadFoo(string name)
{
Foo foo = new Foo();
foo._name = name;
foo._bar = GetOrAddBar();
return foo;
}
public class Foo
{
public string _name;
public Bar _bar;
}
public class Bar
{
public string _name;
}
}