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:
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, . ?
!