How to create a lambda expression that can process or introduce unknown types?

How do you create a lambda expression for a function that can handle unknown types? Sorry, I know that the question is not clear, and it was difficult for me to formulate it. I can only hope you have a minute and read my story, which should sort it out a bit.

My goal is to deserialize an array of string values ​​into an object using a predefined data contract. Members of a data contract have a position number. A simple task of a deserializer is to compare a value with a data element (after the appropriate type conversion) and construct an object.

The problem is that deserialization performance sucks! After starting VS Profiler, I found that PropertyInfo.SetValue (), which is used to populate the elements of an object, takes the most time. My program must deserialize thousands of objects at any given time. A data contract usually has 100 members. So we are talking about 100,000 calls to SetValue () for every 1000 objects and drag and drop them. Here is a sample call to SetValue:

// for each data contract type
// go through each property and set the value
foreach(PropertyInfo pi in pis)
{
    object data = convertStringToMemberType(pi, attributeArray, valueStringArray);
    pi.SetValue(objectToBuild, data, null);
}

Unknown Recipes, . , - SetValue, . , SetValue(). - Action, -.

-, PropertyInfo.

public static class PropertyInfoExtensions
{

    public static Action<object, object> GetValueSetter(this PropertyInfo propertyInfo)
    {
        var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
        var argument = Expression.Parameter(typeof(object), "a");
        var setterCall = Expression.Call(
            instance,
            propertyInfo.GetSetMethod(),
            Expression.Convert(argument, propertyInfo.PropertyType));
        return (Action<object, object>)Expression.Lambda(setterCall, instance, argument).Compile();
    }
}

Dictionary<PropertyInfo, Action<object, object>, propertyInfo Action. , "" . :

foreach(PropertyInfo pi in pis)
{
    object data = convertStringToMemberType(pi, attributeArray, valueStringArray);
    var setValueDelegate = _actionDelegateDict[pi];
    setValueDelegate(objectToBuild, data);
}

:

Unable to cast object of type 'System.Action`2[Test.DataContract1,System.Object]' to type 'System.Action`2[System.Object,System.Object]'.

DataContract1 , . , Unknown Recipes, . ?

!

+3
2

, FastReflection. , , .

, , , , .

public static class PropertyInfoExtensions
{
    public static Action<object, object> GetValueSetter(this PropertyInfo propertyInfo)
    {
        var instance = Expression.Parameter(typeof(object), "i");
        var argument = Expression.Parameter(typeof(object), "a");
        var setterCall = Expression.Call(
            Expression.Convert(instance, propertyInfo.DeclaringType),
            propertyInfo.GetSetMethod(),
            Expression.Convert(argument, propertyInfo.PropertyType));
        return Expression.Lambda<Action<object,object>>(setterCall, instance, argument).Compile();
    }
}
+3

, , Expression s. ? Action<object, object>:

Action<object, object> action = (object i, object a) => i.Property = a;

, i, a. :

Action<object, object> action =
    (object i, object a) => ((DataContract)i).Property = (PropertyType)a;

a, i:

public static Action<object, object> GetValueSetter(this PropertyInfo propertyInfo)
{
    var instance = Expression.Parameter(typeof(object), "i");
    var argument = Expression.Parameter(typeof(object), "a");
    var setterCall = Expression.Call(
        Expression.Convert(instance, propertyInfo.DeclaringType),
        propertyInfo.GetSetMethod(),
        Expression.Convert(argument, propertyInfo.PropertyType));
    return (Action<object, object>)Expression.Lambda(setterCall, instance, argument).Compile();
}
+4

All Articles