What's the easiest way to generate code dynamically in .NET 4.5?

前端 未结 4 1129
旧时难觅i
旧时难觅i 2020-12-31 23:41

I\'m writing a specific kind of object-mapper. Basically I want to convert from a DataTable that has the fields a, b and c

4条回答
  •  情歌与酒
    2021-01-01 00:11

    The easiest way to generate code dynamically in .NET 3.5+ is by converting LINQ Expression Trees to executable code through the Compile method of the LambdaExpression class. .NET 4.0 has greatly expanded the possibilities, adding support for code structures beyond simple expressions of .NET 3.5, letting you construct fully functional methods. The resultant code gives you the same high performance as regularly compiled code would, assuming that your expression generator has applied the same kinds of optimizations a C# compiler would while generating the code.

    Here is how you could generate the code from your snippet:

    // nameToProperty is a dictionary with keys representing string parameters
    // that you pass to drow's indexer, and values representing names of properties
    // or fields of the target object.
    private static Action MakeGetter(IDictionary nameToProperty) {
        var sequence = new List();
        var drowParam = Expression.Parameter(typeof(DataRow));
        var oParam = Expression.Parameter(typeof(T));
        var indexer = typeof(DataRow)
            .GetDefaultMembers()
            .OfType()
            .Where(pinf => pinf.GetIndexParameters().Length == 1
                   &&      pinf.GetIndexParameters()[0].ParameterType == typeof(string))
            .Single();
        foreach (var pair in nameToProperty) {
            var indexExpr = Expression.Property(
                drowParam
            ,   indexer
            ,   Expression.Constant(pair.Key));
            sequence.Add(Expression.Assign(
                Expression.PropertyOrField(pair.Value)
            ,   indexExpr
            ));
        }
        return (Action)Expression.Lambda(
            Expression.Block(sequence)
        ,   drowParam
        ,   oParam
        ).Compile();
    }
    

    With this method in place, you should be able to generate compiled Actions that would do the assignments as needed.

提交回复
热议问题