Static Dictionary fields used to implement static method - c#

Inside a class I have some properties, two static Dictionaries (private fields) a one static method. The method initializes the properties querying the dictionaries and after a switch returns a string. For some reason the values is always returned as null. Below a simplified version:
using System;
using System.Collections.Generic;
namespace Test
{
class Program
{
public static string first { get; set; }
public static string second { get; set; }
public static string third { get; set; }
private static Dictionary<int, string> Symbols = new Dictionary<int, string>
{
[1] = "A",
[2] = "B",
[3] = "C"
};
private static Dictionary<int, string> Encoding = new Dictionary<int, string>
{
[1] = first,
[2] = second,
[3] = third
};
public static string Encode (int n)
{
string result;
first = Symbols[1];
second = Symbols[2];
third = Symbols[3];
switch (n)
{
case 1:
result = Encoding[1];
break;
case 2:
result = Encoding[2];
break;
case 3:
result = Encoding[3];
break;
default:
result = "EMPTY";
break;
}
return result;
}
static void Main(string[] args)
{
Console.WriteLine(Encode(1));
}
}
}
Encode(4) for example returns, correctly, the string "EMPTY" but from 1 to 3 return null. I'm missing something? Is there any more correct/clean way to do the same thing? Thanks!

The method initializes the properties querying the dictionaries and after a switch returns a string.
Yes, when the method is called, the properties will be initialized. Happens after the Encoding dictionary is populated though. The Encoding dictionary is populated as soon as the type is initialized, and at that point, all the properties will have a value of null.
It's not at all clear to me what you're attempting to achieve here, but I would strongly recommend redesigning the code to avoid this confusion.
(I'd also generally warn against having static mutable properties, and I'd at least suggest using regular .NET naming conventions for them.)

Related

return and call several arrays

I have got a method which returns five arrays of different dimensions:
public static (string[],string[],string[,],string[,],string[,]) deserializeobject(string filename)
{
return (Auftraggeber, Aufstellungsort, Anlagen, Vorgang_rückgemeldet, Vorgang_zukünftig);
}
How do I correctly call this method to further work with the arrays?
I would stronly suggest to create a class for that, in particular as the method is public and thus could be used in multiple contexts. That makes it far easier for users of your API to determine the meaning of every returned member.
Your individual members seem to have a descene tmeaning anyway, so why throw it away and return a collection of namesless paramaters?
class MyObject
{
public string[] Auftraggeber { get; set; }
public string[] Aufstellungsort { get; set; }
public string[] Anlagen { get; set; }
public string[] Vorgang_rückgemeldet { get; set; }
public string[] Vorgang_zukünftig { get; set; }
}
And:
public static MyObject Deserialize(string fileName)
{
return new MyObject { AuftragGeber = ... };
}
Now users of your method can easily determine what the parameters mean:
var o = deserialize(myFile);
DoSomething(o.Aufstellungsort);
which is far easier to read than this:
var o DoSomething(myFile);
DoSomething(o.Item2);
isn´t it? Apart from this it limits typos. In the second case users can easily type Item2 when they actually ment Item1, which may cause headache when debugging. With a descent name for every member those typos are far more unlikely.
First the response to your question:
Given:
public static (string[], string[], string[,], string[,], string[,]) deserializeobject(string filename)
{
// Some value that will be returned... Just doing a test here
return default((string[], string[], string[,], string[,], string[,]));
}
You can:
// Using var
var des1 = deserializeobject("foo.bin");
Console.WriteLine($"Lengths: {des1.Item1.Length}, {des1.Item2.Length}, {des1.Item3.Length}, {des1.Item4.Length}, {des1.Item5.Length}");
// Legal, but too much verbose
(string[], string[], string[,], string[,], string[,]) des2 = deserializeobject("foo.bin");
// Legal too, because in truth the ValueTuple<> struct is used
ValueTuple<string[], string[], string[,], string[,], string[,]> des3 = deserializeobject("foo.bin");
Now, the problem here is that, as I've written in a comment, you need a special type of hate for your coworkers to do this. Why? Because if I ask you, what is Item4, can you give me a response? No :-) Fortunately there are two alternatives: creating a full class/struct to contain the return value or using named tuples. I'm quite against creating a class that will be used only by a single method, so I'll show you the named tuples way.
Using named tuples you can:
public static (string[] Auftraggeber, string[] Aufstellungsort, string[,] Anlagen, string[,] VorgangRückgemeldet, string[,] VorgangZukünftig) deserializeobject2(string filename)
{
return default((string[], string[], string[,], string[,], string[,]));
}
Then you can:
// Using var, with named arguments:
var des4 = deserializeobject2("foo.bin");
Console.WriteLine($"Lengths: {des4.Auftraggeber.Length}, {des4.Aufstellungsort.Length}, {des4.Anlagen.Length}, {des4.VorgangRückgemeldet.Length}, {des4.VorgangZukünftig.Length}");
See? The name of the items (arrays) returned by your method is maintained...
Note that named tuples are a sleight of hand. There are no named tuples underside. There are only ValueTuple<> that are "annotated" with the name of the properties that you want.
This is legal:
ValueTuple<string[], string[], string[,], string[,], string[,]> des5 = des4;
Full example to the question in comment:
public static (string[] Auftraggeber, string[] Aufstellungsort, string[,] Anlagen, string[,] VorgangRückgemeldet, string[,] VorgangZukünftig) deserializeobject2(string filename)
{
// Define/create/fill the arrays
var auftraggeber = new string[10];
var aufstellungsort = new string[10];
var anlagen = new string[10, 10];
var vorgangRückgemeldet = new string[10, 10];
var vorgangZukünftig = new string[10, 10];
// Return the arrays
return (auftraggeber, aufstellungsort, anlagen, vorgangRückgemeldet, vorgangZukünftig);
}
use Tuple<> like below code :
public Tuple<int[], int[]> GetMultipleValue(string name)
{
int[] a = new int[]{1,2,3,4}
int[] b = new int[]{5,6,7,8}
return Tuple.Create(a,b);
}

Enum Display Name - Use variable?

Can I do this ? It doesn't seem so.
public enum Options
{
[Display(Name = string.Format("{0} - {1}","Option One", MyClass.myVariable))]
OptionOne=1,
[Display(Name = string.Format("{0} - {1}","Option Two", MyClass.myVariable))]
OptionTwo=2
}
As opposed to this
public enum Options
{
[Display(Name = "Option 1")]
OptionOne=1,
[Display(Name = "Option 2")]
OptionTwo=2
}
If not, how can I make the Display Name for an enum variable ?
Seems like nobody's dealing with:
If not, how can I make the Display Name for an enum variable ?
I can think about some kind of enum map plus extension method which could work like this:
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
public enum Foo
{
One = 1,
Two = 2,
}
public static class ExtensionMethods
{
private static readonly Dictionary<Enum, string> s_EnumMap = new Dictionary<Enum, string>
{
{ Foo.One, string.Format("{0} - {1}","Option One", 1) },
{ Foo.Two, string.Format("{0} - {1}","Option Two", 2) }
};
public static String ConvertToString(this Enum eff)
{
return s_EnumMap[eff];
}
}
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine(Foo.One.ConvertToString());
Console.WriteLine(Foo.Two.ConvertToString());
}
}
}
Integers 1 and 2 can be of course replaced by e.g. static variable, such as MyClass.myVariable. If that is the way you would use this code, then keep in mind that s_EnumMap will store the values that MyClass.myVariable variable had at the time when you first used ExtensionMethods class (i.e. when static fields of MyClass were getting initialized). So modifying the code like this:
public MyClass
{
public static int myVariable = 5;
}
public static class ExtensionMethods
{
private static readonly Dictionary<Enum, string> s_EnumMap = new Dictionary<Enum, string>
{
{ Foo.One, string.Format("{0} - {1}","Option One", MyClass.myVariable) },
{ Foo.Two, string.Format("{0} - {1}","Option Two", 2) }
};
public static String ConvertToString(this Enum eff)
{
return s_EnumMap[eff];
}
}
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine(Foo.One.ConvertToString());
Console.WriteLine(Foo.Two.ConvertToString());
MyClass.myVariable = 100;
Console.WriteLine(Foo.One.ConvertToString());
Console.WriteLine(Foo.Two.ConvertToString());
}
}
Would result into:
Option One - 5
Option Two - 2
Option One - 5
Option Two - 2
While after commenting out the first two Console.WriteLines, the output would be:
Option One - 100
Option Two - 2
So if you want to dynamicaly react to changes of MyClass.myVariable then you have to implement some logic to update s_EnumMap`, but as long as I don't know more about the goal you are trying to achieve I cannot provide a better answer.
You could write a separate method to get the display name, or even a small class that has an option member and a display name member. I like Michal's idea better, but since I already started writing this I figured I'd throw it out there!
public enum Option
{
OptionOne = 1,
OptionTwo = 2
}
public static string GetOptionDisplayName(Option option)
{
switch (option)
{
case Option.OptionOne:
return string.Format("{0} - {1}", "Option One", MyClass.MyProperty);
case Option.OptionTwo:
return string.Format("{0} - {1}", "Option Two", MyClass.MyProperty);
default:
return option.ToString();
}
}
public class AnotherOption
{
public Option Option { get; set; }
public string DisplayName
{
get { return GetOptionDisplayName(this.Option); }
}
}
What you want cannot be done. The compiler needs to know the value at compile time.
The short answer no. The value within [Display....] can be known at compile time only. E.g. you can define literals, like string or enum value. string.Format() is called at run time. If possible you should call it in you other logic, using you enum. Or use code generating, e.g. with a tt template

Creating a non-static version of compiler-based "dictionary" where keys are types

There is a very easy trick which creates a dictionary-like structure where keys are types.
The structure acts like a Dictionary<Type, T?> where keys are Type objects and values are instances of the corresponding types.
This wonderful structure is as fast as just a variable or array since the "lookup" is only done once by the compiler/JITter and the proper value reference is compiled into your program.
public static class MyDict<T> {
public static T Value { get; set; }
}
You can work with that structure like this:
MyDict<string>.Value = MyDict<int>.Value.ToString();
The problem is that this "dictionary" is global. The only way to create different dictionaries is to create different classes.
How can create a similar (fastest "lookup", no boxing) non-static structure? (Without code generation.)
Simply said: I want to have multiple Dictionary<Type, object>-like objects without lookup costs, casting and boxing.
Here's an approach that extends the method described in the question:
public class TypeDict
{
public T Get<T>()
{
return MyDict<T>.Values[this];
}
public void Set<T>(T value)
{
MyDict<T>.Values[this] = value;
}
private static class MyDict<T>
{
public static Dictionary<TypeDict, T> Values { get; private set; }
static MyDict()
{
Values = new Dictionary<TypeDict, T>();
}
}
}
Now we can use the TypeDict like this:
void X()
{
var a = new TypeDict();
var b = new TypeDict();
a.Set<int>(1);
a.Set<double>(3.14);
a.Set("Hello, world!");
//Note that type inference allows us to omit the type argument
b.Set(10);
b.Set(31.4);
b.Set("Hello, world, times ten!");
Console.WriteLine(a.Get<int>());
Console.WriteLine(a.Get<double>());
Console.WriteLine(a.Get<string>());
Console.WriteLine();
Console.WriteLine(b.Get<int>());
Console.WriteLine(b.Get<double>());
Console.WriteLine(b.Get<string>());
}
Ark-kun is using generics to essentially generate unique types at compile time. With a generic type, any static members are unique to that specific closed generic type. This way it's processed as fast as a standard static member lookup.
The above usage is equivalent to something like this:
public static class MyDict_String
{
public static string Value { get; set; }
}
public static class MyDict_Int32
{
public static int Value { get; set; }
}
MyDict_String.Value = MyDict_Int32.Value.ToString();
AFAIK, types are "static" (in that you can't define more than one that way) so I don't know of a way to cheat around this and maintain the same performance of a statically compiled member lookup.
Your best bet otherwise (I think) is to create a generic instance type that wraps its own dictionary that uses System.Type for its keys and System.Object for its values to which you have to perform boxing/casting when inserting/retrieving values.
EDIT: Here's a simple implementation wrapping a dictionary:
public class MyTypedDict
{
private Dictionary<Type, object> Values = new Dictionary<Type, object>();
public T Get<T>()
{
object untypedValue;
if (Values.TryGetValue(typeof(T), out untypedValue))
return (T)untypedValue;
return default(T);
}
public void Set<T>(T value)
{
Values[typeof(T)] = value;
}
}
Thinking about it more, it might be possible to achieve a more property-like syntax using an ExpandoObject (http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx) through some tomfoolery, but I feel like this would be pretty abusive and I can only assume terribly prone to runtime errors. (plus it would afford you nothing at compile time)
EDITx2: If you really want to have different sets of values, you could nest it within another generic type:
public static class ValueSets<T>
{
public static class MyDict<U>
{
public static U Value { get; set; }
}
}
With usage like:
ValueSets<int>.MyDict<string>.Value = "Hello ";
ValueSets<bool>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<int>.MyDict<string>.Value + ValueSets<bool>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
But then the initial type int and bool in this case become "magical" and without meaning, plus you would need to provide a unique type per distinct set of values you'd like to use. Plus you could not pass it around and modify as an instance variable, rather it'd be statically accessible (so long as you have access to use the type T). So perhaps you could declare minimally visible types that are named with meaning and use those:
internal class MyFirstWords {}
internal class MySecondWords {}
ValueSets<MyFirstWords>.MyDict<string>.Value = "Hello ";
ValueSets<MySecondWords>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<MyFirstWords>.MyDict<string>.Value + ValueSets<MySecondWords>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
Regardless, I think this is quite wacky and I wouldn't recommend it.
A more complicated version. Don't know if it's closer:
Define a generic dictionary:
public class MyDictionary<T>
{
Dictionary<string, T> dict;
public MyDictionary()
{
dict = new Dictionary<string, T>();
}
public T this[string name]
{
get
{
if (dict.ContainsKey(name))
return dict[name];
else
return default(T);//or throw
}
set
{
dict[name] = value;
}
}
}
Then a repository to store those dictionaries:
public class MyRepository
{
List<object> repo;
public MyRepository()
{
repo = new List<object>();
}
public void Add<T>(string name, T value)
{
if (!repo.OfType<MyDictionary<T>>().Any())
repo.Add(new MyDictionary<T>());
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
dict[name] = value;
}
public T GetValue<T>(string name)
{
if (!repo.OfType<MyDictionary<T>>().Any())
return default(T);//or throw
else
{
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
return dict[name];
}
}
}
And finally you may use this repository:
MyRepository repo = new MyRepository();
repo.Add("A", 1);
repo.Add("B", 1);
int i = repo.GetValue<int>("A") + repo.GetValue<int>("B");
In this example, there is MyDictionary<T> boxing to object is left.
From the other side, if your are working with some certain types you may not use thie repository class at all. But utilize separate dictionaties.
MyDictionary<int> intDict = new MyDictionary<int>();
intDict["A"] = 1;
intDict["B"] = 2;
int i = intDict["A"] + intDict["B"];
However it's the same as working with
Dictionary<string, int> intDict = new Dictionary<string, int>();
So the MyRepository class may be edited to use Dictionary<string, T> instead of MyDictionary<T>.
#Konstantin's answer made me remember that there is actually a very fast lookup method - array indexing. This crude PoC code shows a variant of the required structure.
public class TypeDictionary {
static int _maxId = 0;
int _id;
static class Store<T>{
internal static List<T> Values = new List<T>();
}
public TypeDictionary() {
_id = _maxId++;
}
public T GetValue<T>() {
return Store<T>.Values[_id];
}
public void SetValue<T>(T value) {
while(Store<T>.Values.Count < _id) {
Store<T>.Values.Add(default(T));
}
Store<T>.Values[_id] = value;
}
}
This code can be used as follows:
var dict1 = new TypeDictionary();
dict1.SetValue("my string");
string result = dict1.GetValue<string>();
The problem with this solution is it's memory usage caused by the repository being not sparse. This also makes first time value setting more expensive.
Try this:
public class MyDictionary
{
List<object> values;
public MyDictionary()
{
values = new List<object>();
}
public T GetValue<T>()
{
return values.OfType<T>().FirstOrDefault();
}
public bool Add<T>(T value)
{
if (values.OfType<T>().Any())
return false;
else
{
values.Add(value);
return true;
}
}
}
and use it:
var md = new MyDictionary();
md.Add("!!!");
string s = md.GetValue<string>();
This class may store up to one value of type T. But there could corner cases with derived classes and interfaces I guess. You may check, if it suits your need, and probably modify it as you need, if it's close to what you need in general.
What you are looking for is impossible in C#. The language does not support a container that could store multiple objects of different types yet provides a look up method that does not involve casting, boxing or unboxing. You could accomplish something like this with macros in C++, or via a language like javascript where the structure of types can be changed at run-time.
The usage case you are describing fits quite closely with the purpose for which ConditionalWeakTable<TKey,TValue> was added to .NET 4.0. For the purpose you describe, you would include such a table in a static generic class, and then for every class object that's supposed to contain a reference to an item of a particular type you would store into that type's table a reference to object that's supposed to contain the item along with either a reference to the item, or else a reference to a simple item-holder object (note that entries in ConditionalWeakTable will evaporate when an object ceases to exist, but are otherwise immutable, so if you want a mutable association you'll need to create an object to hold it).
Building on #phoog's example with #supercat's suggestion
public class TypeDict
{
public T Get<T>() where T : class
{
T value;
InnerDict<T>.Values.TryGetValue(this, out value);
return value;
}
public void Set<T>(T value) where T : class
{
var cwt = InnerDict<T>.Values;
// lock+remove+add https://github.com/dotnet/coreclr/issues/4545
lock (cwt)
{
cwt.Remove(this);
cwt.Add(this, value);
}
}
private static class InnerDict<T> where T : class
{
public static ConditionalWeakTable<TypeDict, T> Values { get; private set; }
static InnerDict()
{
Values = new ConditionalWeakTable<TypeDict, T>();
}
}
}

Architecturally speaking, how should I replace an extremely large switch statement with something more manageable?

EDIT 1: Forgot to add the nested property curve ball.
UPDATE: I have chosen #mtazva's answer as that was the preferred solution for my specific case. In retrospect, I asked a general question with a very specific example and I believe that ended up confusing everyone (or maybe just me) as to what the question was exactly. I do believe the general question has been answered as well (see the Strategy pattern answers and links). Thanks everyone!
Large switch statements obviously smell and I have seen some links on how you could do this with a dictionary that maps to functions. But I'm wondering if there is a better (or smarter way) to do this? In a way, this is a question I've always sort of had rolling around in the back of my head but never really had a good solution to.
This question stemmed from another question I asked earlier: How to select all the values of an object's property on a list of typed objects in .Net with C#
Here is an example class I'm working with (from an external source):
public class NestedGameInfoObject
{
public string NestedName { get; set; }
public int NestedIntValue { get; set; }
public decimal NestedDecimalValue { get; set; }
}
public class GameInfo
{
public int UserId { get; set; }
public int MatchesWon { get; set; }
public long BulletsFired { get; set; }
public string LastLevelVisited { get; set; }
public NestedGameInfoObject SuperCoolNestedGameInfo { get; set; }
// thousands more of these
}
Unfortunately, this is coming from an external source... imagine a HUGE data dump from Grand Theft Auto or something.
And I want to get just a small cross section of a list of these objects. Imagine we want to be able to compare you with a bunch of your friends' game info objects. An individual result for one user would look like this:
public class MyResult
{
public int UserId { get; set; } // user id from above object
public string ResultValue { get; set; } // one of the value fields from above with .ToString() executed on it
}
And an example of what I want to replace with something more manageable (believe me, I DON'T want to be maintaining this monster switch statement):
const int MATCHES_WON = 1;
const int BULLETS_FIRED = 2;
const int NESTED_INT = 3;
public static List<MyResult> GetMyResult(GameInfo[] gameInfos, int input)
{
var output = new List<MyResult>();
switch(input)
{
case MATCHES_WON:
output = gameInfos.Select(x => new MyResult()
{
UserId = x.UserId,
ResultValue = x.MatchesWon.ToString()
}).ToList<MyResult>();
break;
case BULLETS_FIRED:
output = gameInfos.Select(x => new MyResult()
{
UserId = x.UserId,
ResultValue = x.BulletsFired.ToString()
}).ToList<MyResult>();
break;
case NESTED_INT:
output = gameInfos.Select(x => new MyResult()
{
UserId = x.UserId,
ResultValue = x.SuperCoolNestedGameInfo.NestedIntValue.ToString()
}).ToList<MyResult>();
break;
// ad nauseum
}
return output;
}
So the question is are there any reasonable ways to manage this beast? What I'd really like is a dynamic way to get this info in case that initial object changes (more game info properties are added, for instance). Is there a better way to architect this so it's less clumsy?
I think your first sentence eluded to what is probably the most reasonable solution: some form of dictionary mapping values to methods.
For example, you could define a static Dictionary<int, func<GameInfo, string>>, where each value such as MATCHES_WON would be added with a corresponding lambda that extracts the appropriate value (assuming your constants, etc are defined as shown in your example):
private static Dictionary<int, Func<GameInfo, string>> valueExtractors =
new Dictionary<int, Func<GameInfo, string>>() {
{MATCHES_WON, gi => gi.MatchesWon.ToString()},
{BULLETS_FIRED, gi => gi.BulletsFired.ToString()},
//.... etc for all value extractions
};
You can then use this dictionary to extract the value in your sample method:
public static List<MyResult> GetMyResult(GameInfo[] gameInfos, int input)
{
return gameInfo.Select(gi => new MyResult()
{
UserId = gi.UserId,
ResultValue = valueExtractors[input](gi)
}).ToList<MyResult>();
}
Outside of this option, you could potentially have some sort of file/database/stored lookup with the number and the property name, then use reflection to extract the value, but that would obviously not perform as well.
I think this code is getting out of hand a bit. You're effectively using constants to index properties - and this is creating fragile code that you're looking to use some technique - such as - reflection, dictionaries, etc - to control the increased complexity.
Effectively the approach that you're using now will end up with code like this:
var results = GetMyResult(gameInfos, BULLETS_FIRED);
The alternative is to define an extension method that lets you do this:
var results = gameInfos.ToMyResults(gi => gi.BulletsFired);
This is strongly-typed, it doesn't require constants, switch statements, reflection, or anything arcane.
Just write these extension methods and you're done:
public static class GameInfoEx
{
public static IEnumerable<MyResult> ToMyResults(
this IEnumerable<GameInfo> gameInfos,
Func<GameInfo, object> selector)
{
return gameInfos.Select(gi => gi.ToMyResult(selector));
}
public static MyResult ToMyResult(
this GameInfo gameInfo,
Func<GameInfo, object> selector)
{
return new MyResult()
{
UserId = gameInfo.UserId,
ResultValue = selector(gameInfo).ToString()
};
}
}
Does that work for you?
You can use reflection for theses purposes. You can implement custom attributes, mark your properties, etc. Also, it is dynamic way to get info about your class if it changes.
If you want to manage switch code I would point you at Design Patterns book (GoF) and suggest possibly looking at patterns like Strategy and possibly Factory (thats when we talk about general case use, your case isn't very suited for Factory) and implementing them.
While switch statement still has to be left somewhere after refactoring to pattern is complete (for example, in a place where you select strategy by id), code will be much more maintanable and clear.
That said about general switch maintenance, if they become beast like, I am not sure its best solution given how similar your case statements look.
I am 100% sure you can create some method (possibly an extension method) that will be accepting desired property accessor lambda, that should be used when results are generated.
If you want your code to be more generic, I agree with the suggestion of a dictionary or some kind of lookup pattern.
You could store functions in the dictionary, but they seemly all perform the same operation - getting the value from a property. This is ripe for reflection.
I'd store all your properties in a dictionary with an enum (prefer an enum to a const) as the key, and a PropertyInfo - or, less preferred, a string which describes the name of the property - as the value. You then call the GetValue() method on the PropertyInfo object to retrieve the value from the object / class.
Here's an example where I'm mapping enum values to their 'same named' properties in a class, and then using reflection to retrieve the values out of a class.
public enum Properties
{
A,
B
}
public class Test
{
public string A { get; set; }
public int B { get; set; }
}
static void Main()
{
var test = new Test() { A = "A value", B = 100 };
var lookup = new Dictionary<Properties, System.Reflection.PropertyInfo>();
var properties = typeof(Test).GetProperties().ToList();
foreach (var property in properties)
{
Properties propertyKey;
if (Enum.TryParse(property.Name, out propertyKey))
{
lookup.Add(propertyKey, property);
}
}
Console.WriteLine("A is " + lookup[Properties.A].GetValue(test, null));
Console.WriteLine("B is " + lookup[Properties.B].GetValue(test, null));
}
You can map your const values to the names of the properties, PropertyInfo objects which relate to those properties, functions which will retrieve the property values... whatever you think suits your needs.
Of course you will need some mapping - somewhere along the way you will be depending on your input value (the const) mapping to a specific property. The method by which you can get this data might determine the best mapping structure and pattern for you.
I think the way to go is indeed some kind of mapping from one value (int) to something that is somehow a function that knows how to extract a value.
If you really want to keep it extensible, so that you can easily add some without touching the code, and possibly accessing more complex properties (ie. nested properties, do some basic computation), you may want to keep that in a separate source.
I think one way to do this is to rely on the Scripting Services, for instance evaluating a simple IronPython expression to extract a value...
For instance in a file you could store something like :
<GameStats>
<GameStat name="MatchesWon" id="1">
<Expression>
currentGameInfo.BulletsFired.ToString()
</Expression>
</GameStat>
<GameStat name="FancyStat" id="2">
<Expression>
currentGameInfo.SuperCoolNestedGameInfo.NestedIntValue.ToString()
</Expression>
</GameStat>
</GameStats>
and then, depending on the requested stat, you always end up retrieving the general GameInfos. You can them have some kind of foreach loop with :
foreach( var gameInfo in gameInfos){
var currentGameInfo = gameInfo
//evaluate the expression for this currentGameInfo
return yield resultOfEvaluation
}
See http://www.voidspace.org.uk/ironpython/dlr_hosting.shtml for examples on how to embed IronPython Scripting in a .NET application.
NOTE: when working with this kind of stuff, there are several things you must really be careful about:
this potentially allows someone to inject code in your application ...
you should measure the performance impact of Dynamic evaluation in here
I don't have a solution to your switch problem off the top of my head, but you could certainly reduce the code by using a class that can automatically map all the fields you need. Check out http://automapper.org/.
I would not have written the GetMyResult method in the first place. All it is doing is transforming GameInfo sequence into MyResult sequence. Doing it with Linq would be easier and more expressive.
Instead of calling
var myResultSequence = GetMyResult(gameInfo, MatchesWon);
I would simply call
var myResultSequence = gameInfo.Select(x => new MyResult() {
UserId = x.UserId,
ResultValue = x.MatchesWon.ToString()
});
To make it more succinct you can pass the UserId and ResultValue in constructor
var myResultSequence =
gameInfo.Select(x => new MyResult(x.UserId, x.MatchesWon.ToString()));
Refactor only if you see the selects getting duplicated too much.
This is one possible way without using reflection:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public class GameInfo
{
public int UserId { get; set; }
public int MatchesWon { get; set; }
public long BulletsFired { get; set; }
public string LastLevelVisited { get; set; }
// thousands more of these
}
public class MyResult
{
public int UserId { get; set; } // user id from above object
public string ResultValue { get; set; } // one of the value fields from above with .ToString() executed on it
}
public enum DataType
{
MatchesWon = 1,
BulletsFired = 2,
// add more as needed
}
class Program
{
private static Dictionary<DataType, Func<GameInfo, object>> getDataFuncs
= new Dictionary<DataType, Func<GameInfo, object>>
{
{ DataType.MatchesWon, info => info.MatchesWon },
{ DataType.BulletsFired, info => info.BulletsFired },
// add more as needed
};
public static IEnumerable<MyResult> GetMyResult(GameInfo[] gameInfos, DataType input)
{
var getDataFunc = getDataFuncs[input];
return gameInfos.Select(info => new MyResult()
{
UserId = info.UserId,
ResultValue = getDataFunc(info).ToString()
});
}
static void Main(string[] args)
{
var testData = new GameInfo[] {
new GameInfo { UserId="a", BulletsFired = 99, MatchesWon = 2 },
new GameInfo { UserId="b", BulletsFired = 0, MatchesWon = 0 },
};
// you can now easily select whatever data you need, in a type-safe manner
var dataToGet = DataType.MatchesWon;
var results = GetMyResult(testData, dataToGet);
}
}
}
Purely on the question of large switch statements, it is notable that there are 2 variants of the Cyclomatic Complexity metric in common use. The "original" counts each case statement as a branch and so it increments the complexity metric by 1 - which results in a very high value caused by many switches. The "variant" counts the switch statement as a single branch - this is effectively considering it as a sequence of non-branching statements, which is more in keeping with the "understandability" goal of controlling complexity.

Does C# support the use of static local variables?

Related: How do I create a static local variable in Java?
Pardon if this is a duplicate; I was pretty sure this would have been asked previously, and I looked but didn't find a dupe.
Is it possible for me to create a static local variable in C#? If so, how?
I have a static private method that is used rarely. the static method uses a Regular Expression, which I would like to initialize once, and only when necessary.
In C, I could do this with a local static variable. Can I do this in C#?
When I try to compile this code:
private static string AppendCopyToFileName(string f)
{
static System.Text.RegularExpressions.Regex re =
new System.Text.RegularExpressions.Regex("\\(copy (\\d+)\\)$");
}
...it gives me an error:
error CS0106: The modifier 'static' is not valid for this item
If there's no local static variable, I suppose I could approximate what I want by creating a tiny new private static class, and inserting both the method and the variable (field) into the class. Like this:
public class MyClass
{
...
private static class Helper
{
private static readonly System.Text.RegularExpressions.Regex re =
new System.Text.RegularExpressions.Regex("\\(copy (\\d+)\\)$");
internal static string AppendCopyToFileName(string f)
{
// use re here...
}
}
// example of using the helper
private static void Foo()
{
if (File.Exists(name))
{
// helper gets JIT'd first time through this code
string newName = Helper.AppendCopyToFileName(name);
}
}
...
}
Thinking about this more, using a helper class like this there would yield a bigger net savings in efficiency, because the Helper class would not be JIT'd or loaded unless necessary. Right?
No, C# does not support this. You can come close with:
private static System.Text.RegularExpressions.Regex re =
new System.Text.RegularExpressions.Regex("\\(copy (\\d+)\\)$");
private static string AppendCopyToFileName(string f)
{
}
The only difference here is the visibility of 're'. It is exposed to the classm not just to the method.
The re variable will be initialized the first time the containing class is used in some way. So keep this in a specialized small class.
Not in C#, only in Visual Basic .NET:
Sub DoSomething()
Static obj As Object
If obj Is Nothing Then obj = New Object
Console.WriteLine(obj.ToString())
End Sub
VB.NET have lot of nice things that C# does not have, thats why I choose VB.NET.
Unfortunately, no. I really loved this possibility in C.
I have an idea what you could do.
Create a class that will provide access to instance-specific values, which will be preserved statically.
Something like this:
class MyStaticInt
{
// Static storage
private static Dictionary <string, int> staticData =
new Dictionary <string, int> ();
private string InstanceId
{
get
{
StackTrace st = new StackTrace ();
StackFrame sf = st.GetFrame (2);
MethodBase mb = sf.GetMethod ();
return mb.DeclaringType.ToString () + "." + mb.Name;
}
}
public int StaticValue
{
get { return staticData[InstanceId]; }
set { staticData[InstanceId] = value; }
}
public MyStaticInt (int initializationValue)
{
if (!staticData.ContainsKey (InstanceId))
staticData.Add (InstanceId, initializationValue);
}
}
Can be used this way...
class Program
{
static void Main (string[] args)
{
// Only one static variable is possible per Namespace.Class.Method scope
MyStaticInt localStaticInt = new MyStaticInt (0);
// Working with it
localStaticInt.StaticValue = 5;
int test = localStaticInt.StaticValue;
}
}
It's not a perfect solution, but an interesting toy.
You can only have one static variable of this type per Namespace.Class.Method scope. Won't work in property methods - they all resolve to the same name - get_InstanceId.
C# doesn't support static local variables. In addition to what has been posted above, here's a 2004 MSDN blog entry on the subject: Why doesn't C# support static method variables?
(Same blog entry in the Microsoft's own archive. The Web Archive preserved the comments. Microsoft archive didn't.)
Why not create a static readonly member on your class and initialize it in a static constructor maybe?
This will give you the same performance benefit - it will only get initialised once.
What about this, since you only want it to be initialized if it's used:
private static System.Text.RegularExpressions.Regex myReg = null;
public static void myMethod()
{
if (myReg == null)
myReg = new Regex("\\(copy (\\d+)\\)$");
}
I developed a static class that deals with this problem in a fairly simple manner:
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 within a method like this:
var myVar = StaticLocal<int>.Init(1);
Console.Writeline(++myVar.Value);
On each subsequent call to the method, the value contained in myVar.Value will be the last one it was set to so repeated calls will cause it to output a sequence of natural numbers. The Init() function only sets the value if it has not been previously initialized. Otherwise it just returns a reference to an object containing the value.
It makes use of the [CallerFilePath], [CallerMemberName] and [CallerLineNumber] attributes to track which item in the dictionary is being referred to. This eliminates the possibility of collisions between methods with the same names or calls from the same line numbers.
A few caveats about its usage:
As others have stated, it's worthwhile to consider whether what you're doing really requires the use of static local variables. Their use can sometimes be a sign that your design is flawed and could use some refactoring.
This method of dealing with the problem involves a couple layers of indirection, slowing down the execution of your program. It should only be used if it justifies that cost.
Static local variables can help you to deal with having too many members declared in your class, thus compartmentalizing them where they're used. This should be weighed against the execution time cost but can sometimes be worth it. On the other hand, having so many members being declared within a class may be an indication of design problems worth considering.
Because these values continue to remain in memory after their methods complete execution you must be mindful that using them to store large chunks of memory will prevent garbage-collection until the program completes, thus diminishing your available resources.
This approach is probably overkill for most instances where you would want to use static local variables. Its use of indirection to deal with separate files, methods and lines might be unnecessary for your project, in which case you can simplify it to meet your needs.
Sure. You just have to declare the private static variable outside of the method.
private static readonly System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex( "\\(copy (\\d+)\\)$" );
private static string AppendCopyToFileName( string f )
{
//do stuff.
}
This is effectively what you are doing with the only difference being that "re" has visibility to the entire class as opposed to just the method.
I haven't seen a good generic solution to this yet so I thought I'd come up with my own. I should note however that for the most part(not always) needing static local variables is probably a sign that you should refactor your code for the reasons that have been stated by many people; state is something for the object not a method. I do however like the idea of limiting the scope of variables.
Without further ado:
public class StaticLocalVariable<T>
{
private static Dictionary<int, T> s_GlobalStates = new Dictionary<int, T>();
private int m_StateKey;
public StaticLocalVariable()
{
Initialize(default(T));
}
public StaticLocalVariable( T value )
{
Initialize(value);
}
private void Initialize( T value )
{
m_StateKey = new StackTrace(false).GetFrame(2).GetNativeOffset();
if (!s_GlobalStates.ContainsKey(m_StateKey))
{
s_GlobalStates.Add(m_StateKey, value);
}
}
public T Value
{
set { s_GlobalStates[m_StateKey] = value; }
get { return s_GlobalStates[m_StateKey]; }
}
}
This isn't thread safe of course but it wouldn't take too much work to make it so. It can be used like so:
static void Main( string[] args )
{
Console.WriteLine("First Call:");
Test();
Console.WriteLine("");
Console.WriteLine("Second Call:");
Test();
Console.ReadLine();
}
public static void Test()
{
StaticLocalVariable<int> intTest1 = new StaticLocalVariable<int>(0);
StaticLocalVariable<int> intTest2 = new StaticLocalVariable<int>(1);
StaticLocalVariable<double> doubleTest1 = new StaticLocalVariable<double>(2.1);
StaticLocalVariable<double> doubleTest2 = new StaticLocalVariable<double>();
Console.WriteLine("Values upon entering Method: ");
Console.WriteLine(" intTest1 Value: " + intTest1.Value);
Console.WriteLine(" intTest2 Value: " + intTest2.Value);
Console.WriteLine(" doubleTest1 Value: " + doubleTest1.Value);
Console.WriteLine(" doubleTest2 Value: " + doubleTest2.Value);
++intTest1.Value;
intTest2.Value *= 3;
doubleTest1.Value += 3.14;
doubleTest2.Value += 4.5;
Console.WriteLine("After messing with values: ");
Console.WriteLine(" intTest1 Value: " + intTest1.Value);
Console.WriteLine(" intTest1 Value: " + intTest2.Value);
Console.WriteLine(" doubleTest1 Value: " + doubleTest1.Value);
Console.WriteLine(" doubleTest2 Value: " + doubleTest2.Value);
}
// Output:
// First Call:
// Values upon entering Method:
// intTest1 Value: 0
// intTest2 Value: 1
// doubleTest1 Value: 2.1
// doubleTest2 Value: 0
// After messing with values:
// intTest1 Value: 1
// intTest1 Value: 3
// doubleTest1 Value: 5.24
// doubleTest2 Value: 4.5
// Second Call:
// Values upon entering Method:
// intTest1 Value: 1
// intTest2 Value: 3
// doubleTest1 Value: 5.24
// doubleTest2 Value: 4.5
// After messing with values:
// intTest1 Value: 2
// intTest1 Value: 9
// doubleTest1 Value: 8.38
// doubleTest2 Value: 9
Along the lines of Henk's and BarretJ's answer, I think you can avoid the initialization cost and come even closer by using a property,
private Regex myReg = null;
private Regex MyReg
{
get {
if (myReg == null)
myReg = new Regex("\\(copy (\\d+)\\)$");
return myReg;
}
}
Then just use MyReg (note the uppercase 'M' in MyReg) everywhere in your code. The nice thing about this solution is that (although the getter is a function call under the hood) the semantics of properties means that you get to write code as if MyReg was a variable.
The above is how I setup "runtime constants" that require a one-time initialization at runtime.
I do the same thing using nullable types, too. For example,
private bool? _BoolVar = null;
private bool BoolVar
{
get {
if (_BoolVar.HasValue)
return (bool)_BoolVar;
_BoolVar = /* your initialization code goes here */;
return (bool)_BoolVar;
}
}
Then just use BoolVar like a regular normal bool in your code. I don't use internal _BoolVar (the backing store for the BoolVar property) because I just don't need to, remember this is like a runtime constant, so there is no setter. However, if I needed to change the value of the runtime constant for some reason, I'd do that directly on the nullable variable _BoolVar.
The initialization could be pretty involved. But it's only executed one time and only on the first access of the property. And you have the choice of forcing the re-initialization of the runtime constant value by setting _BoolVar back to null.
Nesting the related members in an inner class as you have shown in question is the cleanest most probably. You need not push your parent method into inner class if the static variable can somehow get the caller info.
public class MyClass
{
...
class Helper
{
static Regex re = new Regex("\\(copy (\\d+)\\)$");
string caller;
internal Helper([CallerMemberName] string caller = null)
{
this.caller = caller;
}
internal Regex Re
{
//can avoid hard coding
get
{
return caller == "AppendCopyToFileName" ? re : null;
}
set
{
if (caller == "AppendCopyToFileName")
re = value;
}
}
}
private static string AppendCopyToFileName(string f)
{
var re = new Helper().Re; //get
new Helper().Re = ...; //set
}
private static void Foo()
{
var re = new Helper().Re; //gets null
new Helper().Re = ...; //set makes no difference
}
}
You can avoid hard coding of method names in the property using some expression tree tricks.
You can avoid the helper constructor and make the property static, but you need to get the caller info inside the property, via using StackTrace.
Lastly, there is always const possible inside a method, but then one, it's not variable, two, only compile time constants are allowed. Just stating.
Three years later...
You can approximate it with a captured local variable.
class MyNose
{
private static void Main()
{
var myNose= new MyNose();
var nosePicker = myNose.CreatePicker();
var x = nosePicker();
var y = nosePicker();
var z = nosePicker();
}
public Func<int> CreatePicker()
{
int boog = 0;
return () => boog++;
}
}
I was reading this post recently, because I was courious to know, if the mentioned Visual Basic feature (or C feature, which I wasn't aware) would exist in C# as well.
However, I took some time to put together a solution of all the pre-posts. Some word in advance:
It's not thread safe (but you can bulid it that way)
Because of the use of StackFrame it's painfully slow (as statet in previous post)
The solution approach includes not just static local variables, but also non-static variables with proper memory clean-up
It's bricolage
The tool is this class:
public static class Persistent<T> where T : struct
{
static readonly Dictionary<int, T[]> staticValues;
public static ref T Static(T value)
{
var stackFrameOffset = new StackFrame(1, false).GetNativeOffset();
if (!staticValues.ContainsKey(stackFrameOffset))
staticValues.Add(stackFrameOffset, new T[] { value });
return ref staticValues[stackFrameOffset][0];
}
static readonly ConditionalWeakTable<object, Dictionary<int, T[]>>
nonStaticValues;
public static ref T Local(T value, object callerInstance)
{
var stackFrameOffset = new StackFrame(1, false).GetNativeOffset();
if (!nonStaticValues.TryGetValue(callerInstance, out var storage))
{
storage = new Dictionary<int, T[]>
{
{ stackFrameOffset, new T[] {value} }
};
nonStaticValues.Add(callerInstance, storage);
}
else if (!storage.ContainsKey(stackFrameOffset))
{
storage.Add(stackFrameOffset, new T[] { value });
}
return ref storage[stackFrameOffset][0];
}
static Persistent()
{
staticValues = new Dictionary<int, T[]>();
nonStaticValues = new ConditionalWeakTable<object,
Dictionary<int, T[]>>();
}
}
And the use is like that:
public void Method1()
{
ref int myInt = ref Persistent<int>.Local(0, this);
myInt++;
Console.WriteLine($"myInt is now {myInt}");
}
The same applies for Persistent.Static(77) instead of Local where one is for static values while the other method is vor non-static ones...
If you like to read my considerations about, look here:
https://csatluegisdorf.blogspot.com/2021/11/persistent-variables-for-method-scope.html
Here is sort of a hackish way to accomplish what you're trying to do. Turn MyMethod into an Action that creates a closure on x. The variable x will only be visible to the innermost delegate, and behaves like a static variable. If anyone has any suggestions for improving this pattern let me know.
public static readonly Func<string, string> MyMethod = new Func<Func<string, string>>(delegate ()
{
var x = new Regex("abc", RegexOptions.IgnoreCase); //this Regex will be "static"
return delegate (string input) { return x.Replace(input, "123"); };
}).Invoke();
//example usage:
public void Init()
{
Console.WriteLine(MyMethod("abc")); //console will output "123"
}

Categories