2

I'm a bit out of the loop with the latest features of the C# compiler, so I have to ask this:

Is there a way to get a compiler-generated member function that iterates over all defined and inherited properties of a class (at compile time, as opposed to at run-time by means of reflection) and returns a name-value dictionary?

class Foo
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
    public string D { get; set; }

    [Microsoft.CSharp._SomethingSomething_ToDictionaryConverter]
    // Compiler-generated function:
    // return new Dictionary<string, object>()
    // {
    //     { nameof(Foo.A), this.A },
    //     { nameof(Foo.B), this.B },
    //     { nameof(Foo.C), this.C },
    //     { nameof(Foo.D), this.D },
    // }
    public Dictionary<string, object> ToDict();
}

// Then,
var foo = new Foo();
var d = foo.ToDict();    // yay!
turdus-merula
  • 8,546
  • 8
  • 38
  • 50
  • So you want a reflection-like system without reflection? Lol, that would be nice and a performance killer. – Gusman Aug 01 '17 at 19:11
  • 3
    have you tried to write something for roslyn – Daniel A. White Aug 01 '17 at 19:11
  • @DanielA.White, you've got a point! I didn't, but that seems a very nice idea :) – turdus-merula Aug 01 '17 at 19:13
  • read your code, at compile time? every property will have `default(type)` as those are non-readonly properties... you don't need nothing special to do `default(type)` – Gusman Aug 01 '17 at 19:15
  • 3
    You might be able to do it with a T4 template. – Matt Warren Aug 01 '17 at 19:48
  • And what good would this "compile time dictionary" do that a runtime built one doesn't? How are you planning on leveraging the dictionary at compile time? Or are you just interested in not paying the runtime performance price? – InBetween Aug 01 '17 at 21:24

1 Answers1

3

The desire to remove boilerplate code that is dependent on state that is known in its entirety at compile time is not unique. This is actually what the Fody library was designed to do. It simplifies (relative speaking) the ability to manipulate the final generated IL as part of the build process.

Looking at the list of libraries that are already built, I noticed that the ToString library performs something similar to what you desire. Specifically, it requires consumers to decorate a class with the [ToString] attribute, and the "weaver" will iterate over all of the public properties, override the ToString() method and get it to emit a custom string. In your example, you would create something like a [ToDict] attribute, then create a weaver that would iterate over all of the public properties, define a new ToDict() method, and return a dictionary.

Technetium
  • 5,902
  • 2
  • 43
  • 54