5

所有,我有一个当前用于调用返回类型的 DLL 的方法bool,这很好用。这种方法是

public static bool InvokeDLL(string strDllName, string strNameSpace, 
                             string strClassName, string strMethodName, 
                             ref object[] parameters, 
                             ref string strInformation, 
                             bool bWarnings = false)
{
    try
    {
        // Check if user has access to requested .dll.
        if (!File.Exists(Path.GetFullPath(strDllName)))
        {
            strInformation = String.Format("Cannot locate file '{0}'!",
                                           Path.GetFullPath(strDllName));
            return false;
        }
        else
        {
            // Execute the method from the requested .dll using reflection.
            Assembly DLL = Assembly.LoadFrom(Path.GetFullPath(strDllName));
            Type classType = DLL.GetType(String.Format("{0}.{1}", 
                                         strNameSpace, strClassName));
            if (classType != null)
            {
                object classInstance = Activator.CreateInstance(classType);
                MethodInfo methodInfo = classType.GetMethod(strMethodName);
                if (methodInfo != null)
                {
                    object result = null;
                    result = methodInfo.Invoke(classInstance, new object[] { parameters });
                    return Convert.ToBoolean(result);
                }
            }

            // Invocation failed fatally.
            strInformation = String.Format("Could not invoke the requested DLL '{0}'! " + 
                                           "Please insure that you have specified the namespace, class name " +
                                           "method and respective parameters correctly!",
                                           Path.GetFullPath(strDllName));
            return false;

        }
    }
    catch (Exception eX)
    {
        strInformation = String.Format("DLL Error: {0}!", eX.Message);
        if (bWarnings)
            Utils.ErrMsg(eX.Message);
        return false;
    }
}

现在,我想扩展这个方法,以便我可以从任何类型的 DLL 中检索返回值。我计划使用泛型来做到这一点,但立即进入了我不知道的领域。在编译时未知时如何返回 T,我查看了反射,但我不确定在这种情况下如何使用它。在上面的代码中进行第一次检查

public static T InvokeDLL<T>(string strDllName, string strNameSpace, 
                             string strClassName, string strMethodName, 
                             ref object[] parameters, ref string strInformation, 
                             bool bWarnings = false)
{
    try
    {
        // Check if user has access to requested .dll.
        if (!File.Exists(Path.GetFullPath(strDllName)))
        {
            strInformation = String.Format("Cannot locate file '{0}'!",
                                           Path.GetFullPath(strDllName));
            return "WHAT/HOW??";
        ...

我怎样才能实现我想要的,或者我应该重载方法?

非常感谢您的帮助。

4

3 回答 3

6

代替

return false;

经过

return default(T);

return Convert.ToBoolean(result);

经过

return (T)result;
于 2012-06-22T14:26:15.040 回答
4

当您没有从 DLL 中获得真正的价值时,您显然必须从某个地方创建一个价值。适用于每种可能类型的唯一方法Treturn default(T)给出该类型的默认值(即,0对于任何引用类型)。intnull

如果在类型参数上放置类型约束,您可以获得更多选项,但会牺牲通用性。

于 2012-06-22T14:26:26.050 回答
2

我会做这样的事情:

    public static InvokeDLLResult<T> InvokeDLL<T>(string strDllName, string strNameSpace,
                         string strClassName, string strMethodName,
                         ref object[] parameters,
                         ref string strInformation,
                         bool bWarnings = false)
    {
        try
        {
            // Check if user has access to requested .dll.
            if (!File.Exists(Path.GetFullPath(strDllName)))
            {
                strInformation = String.Format("Cannot locate file '{0}'!",
                                                         Path.GetFullPath(strDllName));
                return InvokeDLLResult<T>.Failure;
            }
            else
            {
                // Execute the method from the requested .dll using reflection.
                Assembly DLL = Assembly.LoadFrom(Path.GetFullPath(strDllName));
                Type classType = DLL.GetType(String.Format("{0}.{1}", strNameSpace, strClassName));
                if (classType != null)
                {
                    object classInstance = Activator.CreateInstance(classType);
                    MethodInfo methodInfo = classType.GetMethod(strMethodName);
                    if (methodInfo != null)
                    {
                        object result = null;
                        result = methodInfo.Invoke(classInstance, new object[] { parameters });
                        return new InvokeDLLResult<T>(true, (T) Convert.ChangeType(result, methodInfo.ReturnType));
                    }
                }

                // Invocation failed fatally.
                strInformation = String.Format("Could not invoke the requested DLL '{0}'! " +
                                                         "Please insure that you have specified the namespace, class name " +
                                                         "method and respective parameters correctly!",
                                                         Path.GetFullPath(strDllName));
                return InvokeDLLResult<T>.Failure;

            }
        }
        catch (Exception eX)
        {
            strInformation = String.Format("DLL Error: {0}!", eX.Message);
            if (bWarnings)
                Debug.WriteLine(eX.Message);
            return InvokeDLLResult<T>.Failure;
        }
    }

    public class InvokeDLLResult<T>
    {
        public InvokeDLLResult(bool success, T result)
        {
            Success = success;
            Result = result;
        }

        public bool Success { get; private set; }
        public T Result { get; private set; }

        public static InvokeDLLResult<T> Failure = new InvokeDLLResult<T>(false, default(T));
    }

或者,我会编写一个 TryInvokeDLL 方法,使用 out 参数返回结果。

于 2012-06-22T14:48:45.327 回答