简体   繁体   中英

Make Func<> for a generic type

I have this architecture.

public void Init()
    {
        PropertyInfo[] infos = typeof(Transform).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (PropertyInfo info in infos)
        {
            // Save getter
            MethodInfo method = info.GetGetMethod();
            System.Type returnType = method.ReturnType;


            System.Func<Transform, Vector3> fact = GetFactory<Transform, Vector3>(method);

            Vector3 v = fact(this.Value);
            Debug.Log("Test123 " + v);

            //_getters.Add(info.Name, newMethod);
        }
    }

    static System.Func<T, T1> GetFactory<T, T1>(MethodInfo info)
    {
        return (System.Func<T, T1>)GetFactory(typeof(T), typeof(T1), info);
    }

    static object GetFactory(System.Type type, System.Type type1, MethodInfo info)
    {
        System.Type funcType = typeof(System.Func<,>).MakeGenericType(type, type1);
        return System.Delegate.CreateDelegate(funcType, info);
    }

It even works if method.ReturnType is Vector3 . But I want the func<Transform, Vector3> to be func<Transform, ReturnType> . I have no idea doing this.

Does someone of you know how I can do this?

And I also have no idea how to save the result in a dictionary. Which type can the dictionary be of?

 public Dictionary<string, System.Func<object, object>> _getters = new Dictionary<string, System.Func<object, object>>();

插图

Edit: No ideas?

From what I get from the comment, is that you want to access getters through a string key? If that is the case, you might want to use the code sample below.

The entity you want to access:

class Entity
{
    public int Foo { get { return 42; } }
    public string Bar { get { return "Magic"; } }
}

The class that allows you to access the properties by name:

class PropertyCaller<T>
{
    // Static for each type T
    private static readonly IDictionary<string, Func<T, object>> _propertyLookup;

    static PropertyCaller()
    {
        _propertyLookup = new Dictionary<string, Func<T, object>>();

        Type objectType = typeof (T);

        foreach (PropertyInfo prop in objectType.GetProperties())
        {
            const BindingFlags num = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

            MethodInfo getMethod = prop.GetGetMethod(true);
            _propertyLookup.Add(prop.Name, item => getMethod.Invoke(item, num, null, null, null));
        }
    }

    public static object Call(T obj, string propertyName)
    {
        Func<T, object> f;

        if (!_propertyLookup.TryGetValue(propertyName, out f))
        {
            throw new InvalidOperationException();
        }

        return f(obj);
    }
}

Example usage:

Entity e = new Entity();
var a = PropertyCaller<Entity>.Call(e, "Foo"); // 42
var b = PropertyCaller<Entity>.Call(e, "Bar"); // Magic

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM