Home > Software engineering >  Is there a way to convert static string class property to Dictionary in C#?
Is there a way to convert static string class property to Dictionary in C#?

Time:01-05

public static class somename
{
    public const string abc = "abc 1";
    public const string xyz = "xyz 2";
    public const string vhj = "vhj 3";
}

I wanted to convert this into dictionary object and use this in foreach

Any idea?

CodePudding user response:

You can declare a static readonly dictionary with an initializer, if that's what you mean:

public static readonly Dictionary<string, string> MyDict = 
    new Dictionary<string, string> {{"abc", "abc 1"}, {"xyz", "xyz 2"}, {"vhj", "vhj 3"}};

To generate it from the class you already have, you need to use reflection:

var constants = typeof(somename).GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
    .Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.FieldType==typeof(string));
var myDict = new Dictionary<string, string>();
foreach (var c in constants)
{
    myDict.Add(c.Name, (string)c.GetRawConstantValue());
}

CodePudding user response:

You can't create const dictionary, but you can do it readonly:

public static class somename {
  // We can't assign MyDictionary (readonly)
  // We can't add, remove or change items (IReadOnlyDictionary)
  public static readonly IReadOnlyDictionary<string, string> MyDictionary = new Dictionary<string, string>() {
    { "abc", "abc 1" },
    { "xyz", "xyz 2" },
    { "vhj", "vhj 3" },
  };
}

I've exposed IReadOnlyDictionary<string, string> to prevent unwanted chageing like

somename.MyDictionary["abc"] = "pqr" // typo: `=` instead of `==`

If you want elaborated logic, you can put it into static constructor:

public static class somename {
  public static readonly IReadOnlyDictionary<string, string> MyDictionary;

  static someone() {
    Dictionary<string, string> myDict = new();

    myDict.Add("abc", ComputeAbc());
    myDict.Add("xyz", ComputeXyz());
    myDict.Add("vhj", ComputeVhj());

    MyDictionary = myDict;
  }
}

You can enumerate {Key, Value} pairs in foreach, e.g.

foreach (var pair in somename.MyDictionary) {
  Console.WriteLine($"{pair.Key} == {pair.Value}");
}

CodePudding user response:

As it was stated by many people on this thread you can't really map your static class with const fields to a dictionary with the same runtime guarantees. In order to understand the problem let's define three terms:

  • Const: It has a compile-time guarantee that its value can't be changed.
  • Readonly: It has a run-time guarantee that once it is initialized it can't be changed.
  • Immutable: It has a run-time guarantee that whenever you perform a modification operation then it creates a new version of the object.

Please also bear in mind that objects and collections are treated in a different way. For example if you mark a collection as readonly it means you can't change the reference of the collection to another collection or to null. But it does not prevent you to add/remove items to/from the collection.

That's there are ReadonlyDictionary and ImmutableDictionary.

The closest thing what you can get is to use ImmutableDictionary as an implementation and expose it as an IReadonlyDictionary.

public readonly IReadOnlyDictionary<string, string> somenames = new Dictionary<string, string>
{
    { "abc", "abc 1" },
    { "xyz", "xyz 2" },
    { "vhj", "vhj 3" }
}.ToImmutableDictionary();

There are several ways to build an immutable collections. Here I have listed a couple of options.

  • Related