0

I am wanting to create a 'dictionary' of strings, however I have only ever learned how to use strings to reference what I want in a dictionary. I want something with more auto-correct (as typos can happen in a large table of strings), which is why I want to know how to hard-code. (The value of the strings will be retrieved from a text file, like JSON).

I notice that Microsoft uses some type of hard-coding in their String Resource File.

So instead of doing:

string result = strings["Hello"];

I wish to do this:

string result = strings.Hello;

The only thing I can think of is to use some external tool that creates an enum/struct script with the values from the text file. Is there a better option, perhaps one built into .NET?

Edit: I think 'strongly-typed' would be a better description over 'hard-coded'.

Edit 2: Thanks for all the comments and answers. By the looks of it, some code-gen is required to fufil this result. I wonder if there's already any tools out there that do this for you (I tried looking but my terminology may be lacking). It doesn't seem too difficult to create this tool.

Dynamiquel
  • 105
  • 1
  • 6
  • You could use T4 templates? I've done that in the past and it works well enough, provided that you remember to regenerate them as appropriate – canton7 Feb 03 '20 at 14:44
  • If you want full intellisensing, you'll have to code-gen some static classes, as @canton7 suggests. If you're willing to forego intellisense, you can try an [ExpandoObject](https://learn.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject?redirectedfrom=MSDN&view=netframework-4.8). – Robert Harvey Feb 03 '20 at 14:46
  • There is the generic Readonly Collection: https://learn.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.readonlycollection-1 | It will not have the performance advantages of compile time constants/Enums, but at least using code can not change it. – Christopher Feb 03 '20 at 14:48
  • 1
    Have you looked at the code behind a resource file? There's a property for each keys. – the_lotus Feb 03 '20 at 14:49
  • @Christopher: That's not what the OP wants. – Robert Harvey Feb 03 '20 at 14:49
  • @the_lotus: Yes. It's code-genned. – Robert Harvey Feb 03 '20 at 14:50
  • how you plan to load that dictionary? can the [satellite assemblies](https://stackoverflow.com/questions/365569/what-is-a-satellite-assembly/21263797) be an option? – Rubens Farias Feb 03 '20 at 14:51
  • 1
    @RubensFarias: I assume that the OP doesn't want to compile and load this stuff on the fly, because he wrote `string result = strings.Hello;` Otherwise, it's more or less [Assembly.LoadFrom](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.assembly.loadfrom?redirectedfrom=MSDN&view=netframework-4.8#overloads) – Robert Harvey Feb 03 '20 at 14:56
  • @RobertHarvey I was a bit pressed for time, but now I wrote a hopefully better answer. – Christopher Feb 03 '20 at 16:00

2 Answers2

1

There are compiletime constants and runtime constants.

Your wish for Autocrrection/Intellisense support requires a compile time constants. Those are the only ones Intellisence, Syntax Highlighting and the Compiler double check for you.

But your requriement of having the values generated from a 3rd party textfile, indicates either a runtime constant or some automatic code generation. Runtime constants would take away the Editor support. While Code generation would run into issue with the Editor only having a old copy of the file. And a high risk of breaking tons of code if a string in that one file changes.

So your two requirements are inherently at odds. You need to have your cake and eat it too.

Perhaps my primitve solution to the Enum/ToString() problem might help you?

Enumeration are for most parts groups of constants, and integer ones by default. With added type checks on assignments. That makes them a good way around Primitive Obsession. You reference a value from the group like you would any constant, readonly static field or readonly property. (There is other advantages like Flags, but I doubt they mater here).

While Enums have a string you could use for display and input parsing - the one you use in sourcecode - that one is absolutely not suited for display. By default they are all-caps and you would need to support Localisation down the line. My primitive Solution was a translation layer. I add a Dictionary<someEnum, String> SomeEnumStringRepresentation. This dictionary can be generated and even changed at runtime:

  • I need to display any specific value, it is SomeEnumLocalisation[someEnum]. I could add a default behavior to just ToString() the compiler representation of the Enum.
  • I need to parse a user input? Itterate over the values until you find a match, if not throw a ParseException.
  • I get to use compile time checks. Without having to deal with the very inmutable compile side strings anywhere else. Or with my code side strings changing all the time.
Christopher
  • 9,634
  • 2
  • 17
  • 31
-2

i am not quit understand what out put you want , bu I am just throwing an idea to here - how about to extend the class string and add your own methods to it ? so when you use strings.Hello it will return what you wanted?

example : https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods

  • 1
    I don't think this answers the OP's question, which is how to *generate* a set of properties for some class (see their `strings` variable) – canton7 Feb 03 '20 at 14:57