2

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

Community
  • 1
  • 1
allanmb
  • 321
  • 3
  • 14
  • Surely you couldn't "forget" because anywhere you're adding items to the dictionary would fail due to the strongly-typed generic constraint not being satisfied. – Grant Thomas Sep 02 '13 at 10:04
  • Actually I believe that I won't do that. Why having the actual type name is unreadable? Maybe `ConfigValue` instead of `List` seems more "readable", but I wouldn't know the actual type by just reading the code... – Matías Fidemraizer Sep 02 '13 at 10:31

2 Answers2

3

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.

Magnus Grindal Bakken
  • 2,083
  • 1
  • 16
  • 22
-1

You can't, and using x = y is not supposed to be used to create type aliases. It's supposed to be used to create namespace aliases, to resolve conflicts (e.g., a namespace and a class sharing the same name).

dcastro
  • 66,540
  • 21
  • 145
  • 155
  • Using **can** be use used to create type [aliases](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive) . Their scope only in the current source file, though. – ceztko Nov 20 '19 at 11:24