Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save imgen/228914016be4f971f8b495c74abef5d7 to your computer and use it in GitHub Desktop.

Select an option

Save imgen/228914016be4f971f8b495c74abef5d7 to your computer and use it in GitHub Desktop.

Revisions

  1. @leandromoh leandromoh renamed this gist Jun 9, 2020. 1 changed file with 0 additions and 0 deletions.
  2. @leandromoh leandromoh created this gist Jun 9, 2020.
    39 changes: 39 additions & 0 deletions Anonymous type with Expression
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,39 @@
    public static class AnonymousExtension
    {
    static void Main(string[] args)
    {
    var person = new { FirstName = "Scott", LastName = "Hunter", Sex = 'M', Age = 25 };

    var otherPerson = person.With(new { LastName = "Hanselman" });

    Console.WriteLine(otherPerson);
    }

    public static T With<T, U>(this T x, U y)
    {
    return AnonymousHelper<T, U>.Create(x, y);
    }

    private static class AnonymousHelper<T, U>
    {
    public static readonly Func<T, U, T> Create;

    static AnonymousHelper()
    {
    ParameterExpression x = Expression.Variable(typeof(T), "x");
    ParameterExpression y = Expression.Variable(typeof(U), "y");
    var ctr = typeof(T).GetConstructors()[0];
    var values = ctr.GetParameters()
    .Select(p =>
    {
    var instance = typeof(U).GetProperty(p.Name, p.ParameterType) is null ? x : y;
    return Expression.Property(instance, p.Name);
    });

    var exp = Expression.New(ctr, values);
    var lam = Expression.Lambda<Func<T, U, T>>(exp, new[] { x, y });

    Create = lam.Compile();
    }
    }
    }