.net - 委托(delegate)返回类型的问题

标签 .net reflection delegates .net-2.0

有以下代码

public delegate object ParseHandler(string s);
public static ParseHandler GetParser(Type t)
{
    MethodInfo parse = t.GetMethod("Parse", BindingFlags.Static | BindingFlags.Public,
        null, new Type[] { typeof(string) }, null);

    if (parse != null)
        return (ParseHandler)Delegate.CreateDelegate(typeof(ParseHandler), parse, true);

    return null;
}

Delegate.CreateDelegate() 调用上发生错误,并显示“绑定(bind)到目标方法时出错”。显然是因为 ParseHandler 被定义为返回 object 而不是类型特定的返回值。

我不知道编译类型的类型,因此我无法将 type 参数替换为泛型(如果我这样做,则不需要整个函数)。

对于如何处理这个问题有点困惑。所需的行为是找到给定类型的 public static Parse(string) 方法并创建一个委托(delegate)以供稍后调用。

最佳答案

只要真正的返回值是引用类型就应该没问题 - 但对于值类型返回值来说失败是有道理的。 (有关更详细的说明,请参阅 Eric Lippert 关于 representation and identity 的帖子。)

一种选择是创建一个像这样的泛型类:

public class BoxingParserDelegate<T>
{
    private readonly Converter<string, T> parser;

    public BoxingParserDelegate(Converter<string, T> parser)
    {
        this.parser = parser;
    }

    public object Parse(string x)
    {
        return parser(x);
    }
}

在 GetParser 方法中,您将检查返回类型是否 parse是值类型,如果是,则创建 BoxingParserDelegate<T> 的实例通过反射。然后您可以创建 ParseHandler BoxingParserDelegate 的 Parse 方法的实例.

坦率地说,这一切都会有点尴尬,但应该可行。说实话,感觉应该有一种更简单的方法。

(在 .NET 3.5 或更高版本上,我建议使用表达式树,但我只见过 .NET 2.0 标记。)

编辑:啊哈,想到了稍微简单的方法:

public static ParseHandler BuildParseHandler<T>(Converter<string, T> converter)
{
    // Performs boxing automatically
    return delegate(string x) { return converter(x); }
}

实际上要求编译器为您完成上述一半的工作。然后你只需要确定是否需要调用它,并在必要时进行反射(reflection)。像这样的事情:

public static ParseHandler GetParser(Type t)
{
    MethodInfo parse = t.GetMethod("Parse",
        BindingFlags.Static | BindingFlags.Public,
        null, new Type[] { typeof(string) }, null);

    // Method not found
    if (parse == null)
    {
        return null;
    }

    // Reference type - use delegate covariance
    if (!parse.ReturnType.IsValueType)
    {
        return (ParseHandler) Delegate.CreateDelegate(typeof(ParseHandler),
            parse, true);
    }

    // Tricky situation: call BuildParseHandler with generics
    Type delegateType = typeof(Converter<,>).MakeGenericType(typeof(string),
                                                             parse.ReturnType);
    object converter = Delegate.CreateDelegate(delegateType, parse, true);

    // You may need extra work to get this... let me know whether or not it works.
    // Obviously if you make it private, you'll need extra binding flags.
    MethodInfo method = typeof(TypeContainingThisMethod)
                            .GetMethod("BuildParseHandler");
    method = method.MakeGenericMethod(parse.ReturnType);

    return (ParseHandler) method.Invoke(null, new object[] { converter });
}

关于.net - 委托(delegate)返回类型的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5263735/

相关文章:

ios - viewDidAppear 时如何调用 pickerview 的委托(delegate)?

c# - 是否有用于 C# 的不错的 MongoDB 框架?

.net - 在 DotNet RGB24 或 RGB32 中使用什么来提高性能

c# - GridView 状态问题?

C# : LINQ query to list all empty properties of a class

reflection - Powershell 是否具有 "eval"等效项?有没有更好的方法来查看属性和值的列表?

c# - 尝试使用委托(delegate)进行 catch

c# - 无法在我的电脑中粘贴任何文本或文件 - 剪贴板错误

c++ - 在运行时通过名称访问类成员变量

c# - 关于委托(delegate)的澄清