如何将通过反射实例化的对象转换为其实际类型?

时间:2012-10-27 11:57:53

标签: c#-4.0 reflection c#-3.0 system.reflection

最近我正在为自己开发一个小框架,
我遇到了这个问题:
我怎么能做以下事情:

void object CreateDictionary(Type dictionaryType)
{
    object dict = dictionaryType.GetConstructor(new Type[] {}).Invoke(new object[] {});
    // Cast dict to its real type here so that I can add key-value-pairs to it.
    ...
}

dictionaryType是某种词典的类型,是通过反射获得的 我不知道完整类型,因为直到运行时我才知道通用属性。

我也尝试将声明object dict更改为var dict,但它也不起作用。

2 个答案:

答案 0 :(得分:1)

你不能这样做。但是,你知道这是某种词典,所以你可以将它转换为IDictionary并使用IDictionary的方法。

object CreateDictionary(Type dictionaryType)
{
    object dict = dictionaryType.GetConstructor(new Type[] {}).Invoke(new object[] {});
    var idictionary = (IDictionary)dict;
    idictionary.Add(key, value);
}

如果您所有这些词典都是从一个类继承的,那么您可以将它转换为此类并使用此类的方法。

顺便说一句,通过以下方式获取Type实例更简单:

object obj = Activator.CreateInstance(type);

答案 1 :(得分:0)

好的,我终于设法解决了这个问题 最后我注意到我想做的不是铸造,
但是调用方法。
也许有比我更好的解决方案。 无论如何,我想分享我的解决方案。

首先,为object创建一个扩展类(虽然这很奇怪):

public static class ReflectionHelper
{
    public static object InvokeInstanceMethod(this object invoker, string methodName, params object[] parameters)
    {
        MethodInfo[] methods = invoker.GetType().GetMethods();
        foreach (MethodInfo method in methods)
        {
            ParameterInfo[] paramInfos = method.GetParameters();
            if (method.Name == methodName && paramInfos.Length == parameters.Length)
            {
                for (int i = 0; i < parameters.Length; i++)
                {
                    if (!paramInfos[i].ParameterType.IsAssignableFrom(parameters[i].GetType()))
                    {
                        throw new MissingMethodException();
                    }
                }
                return method.Invoke(invoker, parameters);
            }
        }
        throw new MissingMethodException();
    }
}

这个扩展方法允许我调用这样的方法:

anyInstance.InvokeInstanceMethod("MethodName", param1, param2, ...);

因为所有类型(不包括Object本身)都是从Object派生的,所以此方法可以在任何类型的任何实例上进行校准。

然后我使用这个方法:

object dict = dictionaryType.CreateInstance(); // The method CreateInstance() is also an extension
dict.InvokeInstanceMethod("Add", key, val);