Creating a Generic Func Delegate Using Runtime Type

I need to call a generic method that accepts a generic Func as one of its parameters, where the Type parameter is known only at runtime. This piece of code is a mapper object that maps properties between the source and the target. ViewModelBase is the root of the classes that are considered targets.

The method I want to call (defined in ObjectMapperBuilder) has this signature:

public static ObjectMapperBuilder<TTarget> Create(
    Type sourceType, 
    MappingDirection direction, 
    Func<TTarget, IDictionary<String, object>> getDictionaryFromTarget = null
);

In my base class, I want to call the above method, but use the most derived type as my type parameter:

public ViewModelBase {
    private ConcurrentDictionary<string, object> _propertyValues;

    public ViewModelBase (object sourceObject) {
        Type tTarget = this.GetType();

        // 1. How do I create the Func? All it does is return a private member.
        // This is wrong because it uses a compile-time generic parameter.
        Func<TTarget,IDictionary<String,object>> myFunc = (vm) => vm._propertyValues;

        // 2. Ho do I call the Create method using reflection to specify the 
        //    TTarget generic parameter at runtime?
        var myMapper = ObjectMapperBuilder<TTarget>.Create(
            sourceObject.GetType(), 
            MappingDirection.Bidirectional,
            myFunc
        );
        // Do stuff with myMapper.
        ...
    }

- Mapper . Mapper , mappers , .

, .

:

Func <T>

+4
2

, , :

public class ViewModelBase<T> where T : ViewModelBase<T>

:

public class SubViewModelBase: ViewModelBase<SubViewModelBase>

, :

Func<T, IDictionary<string, object>> props = (vm) => vm._propertyValues;
var mapper = ObjectMapperBuilder<T>.Create(
    sourceObject.GetType(), 
    MappingDirection.Bidirectional,
    props);
0

. GetProperties, , , , Delegate.CreateDelegate.

protected static IDictionary<string, object> GetProperties(ViewModelBase viewModel)
{
    return viewModel._propertyValues;
} 
protected Delegate GetPropertiesFunc()
{
    Type funcType = typeof(Func<,>).MakeGenericType(this.GetType(), typeof(IDictionary<String,object>));
    MethodInfo method = typeof(ViewModelBase).GetMethod("GetProperties",
        BindingFlags.NonPublic | BindingFlags.Static
    );
    return Delegate.CreateDelegate(funcType, method);
} 

Func, GetPropertiesFunc Activator.CreateInstance, .

0

Source: https://habr.com/ru/post/1526198/


All Articles