使Func<>对于通用类型

时间:2015-05-28 16:58:00

标签: c# reflection

我有这种架构。

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);
    }

如果method.ReturnTypeVector3,它甚至有用。 但我希望func<Transform, Vector3>func<Transform, ReturnType>。 我不知道这样做。

你们有人知道我怎么做吗?

而且我也不知道如何将结果保存在字典中。 字典可以使用哪种类型?

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

Illustration

编辑:没有想法?

1 个答案:

答案 0 :(得分:1)

从评论中得到的是,您是否想通过字符串键访问getter?如果是这种情况,您可能希望使用下面的代码示例。

您要访问的实体:

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

允许您按名称访问属性的类:

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);
    }
}

使用示例:

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