I developed a static class that handles this problem in a rather simple way:
using System.Collections.Generic; using System.Runtime.CompilerServices; public static class StaticLocal<T> { static StaticLocal() { dictionary = new Dictionary<int, Dictionary<string, Access>>(); } public class Access { public T Value { get; set; } public Access(T value) { Value = value; } } public static Access Init(T value, [CallerFilePath]string callingFile = "", [CallerMemberName]string callingMethod = "", [CallerLineNumber]int lineNumber = -1) { var secondKey = callingFile + '.' + callingMethod; if (!dictionary.ContainsKey(lineNumber)) dictionary.Add(lineNumber, new Dictionary<string, Access>()); if (!dictionary[lineNumber].ContainsKey(secondKey)) dictionary[lineNumber].Add(secondKey, new Access(value)); return dictionary[lineNumber][secondKey]; } private static Dictionary<int, Dictionary<string, Access>> dictionary; }
It can be implemented as part of a method like this:
var myVar = StaticLocal<int>.Init(1); Console.Writeline(++myVar.Value);
Each subsequent method call, the value contained in myVar.Value will be the last one when it was set so that repeated calls invoked it to output a sequence of natural numbers. The Init () function sets a value only if it has not been previously initialized. Otherwise, it simply returns a reference to the object containing the value.
It uses the attributes [CallerFilePath], [CallerMemberName] and [CallerLineNumber] to track which subject the dictionary refers to. This eliminates the possibility of collisions between methods with the same names or calls from the same line numbers.
A few warnings about use:
- As others have argued, it is worth considering whether what you are doing is necessary to use static local variables. Their use can sometimes be a sign that your design is flawed and may use some refactoring.
- This method of solving the problem involves a couple of levels of indirection that slow down your program. It should be used only if it justifies this cost.
- Static local variables can help you cope with too many members declared in your class, and thus distinguish between where they are used. This should be comparable to the execution time, but sometimes it may be worth it. On the other hand, having so many members declared in a class may indicate design issues that are worth considering.
- Since these values remain in memory after completing their methods, you must remember that using them to store large chunks of memory will prevent garbage collection until the program terminates, which will reduce your available resources.
This approach is likely to be redundant for most cases when you want to use static local variables. Using indirectness to process individual files, methods, and lines may not be necessary for your project, in which case you can simplify it to meet your needs.
bükWyrm Apr 18 '16 at 18:00 2016-04-18 18:00
source share