mercredi 29 juillet 2020

Looking for a more concise way to put a C# setter into a Dictionary<> for mapping

This is a representation of a larger bit of code I’m working on that’s a mapper. Originally it was written as a large switch statement, but I prefer to make the mapping stand out as a table rather than a long, long switch.

My first pass looks something like this (from LINQPad):

    Dictionary<string, Action<Foobar, decimal>> map
        = new Dictionary<string, Action<Foobar, decimal>> {
                { "one", (f,d) => f.One = d },
                { "double", (f,d) => f.Two = d },
                { "tricycle", (f,d) => f.Three = d },
        };
    
    void Main()
    {
        Foobar obj = new Foobar();
        decimal amount = 100M;
        var x = map["one"];
        x(obj, amount);
    
        Console.WriteLine(obj.One);   // Prints 100 as expected
    }
    public class Foobar
    {
        public decimal One { get; set; }
        public decimal Two { get; set; }
        public decimal Three { get; set; }
    }

The real Foobar class is large, has many properties, but they’re all the same type: decimal.

What I’m looking for is a more concise way of expressing the table above. This is fine:

{ "one", (f,d) => f.One = d },          // It works, but … can it be better?

I really don’t want to do it as strings with full-on reflection in the invocation:

{ "one", "One" },                       // No
{ "one", nameof(Foobar.One) },          // Really, just no.

I seem to remember there’s a more concise way to do it, but my Google-fu fails me. I can get to the getter more concisely by changing the signature to Dictionary<string, Func<Foobar, decimal>> and then doing this:

   { "one", f.One }                        // The getter, not the setter.

but that doesn’t get me to the setter. Ideas?





Aucun commentaire:

Enregistrer un commentaire