Let's first give your method an implementation, then we can look at what's going on under the covers.
private static Dictionary<string, object> _LUT;
public static T GetObject<T>(String name, Func<T> creator)
{
object obj;
if (_LUT.TryGetValue(name, out obj))
{
return (T)obj;
}
T ret = creator();
_LUT.Add(name, ret);
return ret;
}
public string GetString(string name)
{
return GetObject<string>(name, () => "Foo");
}
Instructions for GetObject(...):
IL_0000: ldsfld System.Collections.Generic.Dictionary`2[System.String,System.Object] _LUT
IL_0005: ldarg.0
IL_0006: ldloca.s System.Object (0)
IL_0008: callvirt Boolean TryGetValue(System.String, System.Object ByRef)
IL_000d: brfalse.s IL_0016
IL_000f: ldloc.0
IL_0010: unbox.any T
IL_0015: ret
IL_0016: ldarg.1
IL_0017: callvirt T Invoke()
IL_001c: stloc.1
IL_001d: ldsfld System.Collections.Generic.Dictionary`2[System.String,System.Object] _LUT
IL_0022: ldarg.0
IL_0023: ldloc.1
IL_0024: box T
IL_0029: callvirt Void Add(System.String, System.Object)
IL_002e: ldloc.1
IL_002f: ret
Instructions for GetString(...):
IL_0000: ldarg.1
IL_0001: ldsfld System.Func`1[System.String] CS$<>9__CachedAnonymousMethodDelegate1
IL_0006: brtrue.s IL_0019
IL_0008: ldnull
IL_0009: ldftn System.String <GetString>b__0()
IL_000f: newobj Void .ctor(System.Object, IntPtr)
IL_0014: stsfld System.Func`1[System.String] CS$<>9__CachedAnonymousMethodDelegate1
IL_0019: ldsfld System.Func`1[System.String] CS$<>9__CachedAnonymousMethodDelegate1
IL_001e: call System.String GetObject[String](System.String, System.Func`1[System.String])
IL_0023: ret
As you can see, your lambda is being stored in a static field of type System.Func1[System.String]
which is being passed to your method by reference (Why are delegates reference types?), and calling System.Func1[System.String].Invoke()
when needed, so the size of the method should make no difference.
As for your question on whether an alternative exists:
If this is a one-time function you could try System.Lazy
, if you're looking for general Caching support I suggest checking out this: .NET 4 Caching Support