Search code examples
c#.netxnamonogame

How to transform a string to a Definition of an Object


I want to avoid copy/pasting 4 times the same operation with only changing the byte (x0.R to x0.G and so for each color).
I'm not sure if it's possible in C# (.NET 3) but I know something similar exists in different languages (ruby with the method "something".to_sym).

My code here has a local method Blend(string color). x0 and x1 are Color objects which return a byte when I call x0.R corresponding to red, x0.G for green, etc.
I am trying to make it possible for x0.color to work, where color is a string that can be either "R", "G", "B", or "A".

Is there a way in C# to transform x0."R" to x0.R?

private static Color Interpolate(Color x0, Color x1, float alpha)
    {
        float Blend(string color)
        {
            float z = (float) x0.color / 255 * (1- alpha) + alpha * (float) x1.color / 255; 
            return z;
        }
        // float r = (float) x0.R / 255 * (1- alpha) + alpha * (float) x1.R / 255;
        

        return new Color(Blend("R"),Blend("G"),Blend("B"),Blend("A"));
    } 

EDIT : I found a method doing exactly what I wrote from the Object Color (Xna, not System.Drawings) which is to interpolate 2 colors :

private static Color Interpolate(Color x0, Color x1, float alpha)
{
    return Color.Lerp(x0,x1,alpha);
}

Solution

  • I think the closest you'll get is something like this:

    private static Color Interpolate(Color x0, Color x1, float alpha)
    {
        float Blend(Func<Color, byte> componentSelector)
        {
            float z = (float) componentSelector(x0) / 255 * (1 - alpha)
                + alpha * (float) componentSelector(x1) / 255; 
            return z;
        }
    
        return new Color(
            Blend(x => x.R),
            Blend(x => x.G),
            Blend(x => x.B),
            Blend(x => x.A));
    }
    

    At least I don't know of a shorter form of a delegate to select a property. It would be nice with something like Blend(_.R).

    So I think that's your best option unless you want to start doing some reflection, but that's adding complexity for very little gain.