Search code examples
c#coding-stylenestedtypedefusing

Nested 'using' in C# as equivalent to typedef


I have a class to handle config files and I want to tidy up the code to make it more readable and maintainable. In C++ I would usually do this using typedefs but I found that there is a way to do this in C# by using the 'using' keyword (see Equivalent of typedef in C#). My only problem is that there doesn't seem to be a way to nest these. Here is what I want to achieve:

using ConfigValue = System.Collections.Generic.List< System.String >;
using ConfigKey = System.String;
using ConfigSection = System.Collections.Generic.Dictionary< ConfigKey, ConfigValue >;

How can I achieve this without making ConfigSection explicit just in case I change the type of the ConfigKey or ConfigValue and forget to change the ConfigSection?

Thanks

Allan


Solution

  • You can't do this, unfortunately. The main C# alternative to typedef in C/C++ is usually type inference, e.g. with the var keyword, but you still have to type out generic definitions in many cases. There's a reason why almost all C# programmers use Visual Studio or other IDE's that save them from typing out everything in many cases.

    I wouldn't really recommend the "using-as-typedef" pattern too much, because I expect it will be unfamiliar and surprising to most C# programmers. Also, I think the fact that you have to include the "psuedo-typedef" in every file anyway greatly reduces the utility of it.

    One thing you could consider doing is of course to make actual classes out of the things you want to typedef, e.g. like this:

    public class ConfigValue : List<string>
    {
    }
    
    public class ConfigKey
    {
        private string s;
    
        public ConfigKey(string s)
        {
            this.s = s;
        }
    
        // The implicit operators will allow you to write stuff like:
        // ConfigKey c = "test";
        // string s = c;
    
        public static implicit operator string(ConfigKey c)
        {
            return c.s;
        }
    
        public static implicit operator ConfigKey(string s)
        {
            return new ConfigKey(s);
        }
    }
    
    public class ConfigSection : Dictionary<ConfigKey, ConfigValue>
    {
    }
    

    But this is of course overkill unless you also have other reasons to want to make concrete classes.