简体   繁体   中英

Is there a way to convert static string class property to Dictionary in C#?

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?

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());
}

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 , eg

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

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM