Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 委托返回类型的问题_.net_Reflection_Delegates_.net 2.0 - Fatal编程技术网

.net 委托返回类型的问题

.net 委托返回类型的问题,.net,reflection,delegates,.net-2.0,.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 (pa

有以下代码

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调用上爆炸,绑定到目标方法时出错。显然是因为ParseHandler被定义为返回对象,而不是特定于类型的返回值

我不知道编译类型的类型,所以我不能用泛型替换类型参数,如果我这样做了,那么整个函数就不需要了


对如何处理这件事有点困惑。所需的行为是找到给定类型的公共静态Parsestring方法,并为其创建一个委托,以便稍后调用。

只要实际返回值是引用类型,就可以了,但对于值类型返回值,此操作失败是有意义的。请参阅Eric Lippert关于的帖子,以获得更详细的解释

一个选项是创建如下所示的泛型类:

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);
    }
}
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 });
}
这实际上是要求编译器为您完成上述工作的一半。然后,您只需要确定是否需要调用此函数,并在必要时使用反射进行调用。大概是这样的:

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);
    }
}
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 2.0平台上?能否向我们展示它失败的解析方法声明?也许您想要编写的内容与我的解析类似,只是您可能需要用对象替换一些Ts。@Mr.失望是的。@Ani接受任何整型或DateTime这很好,但我建议使用转换器代替;OP在.NET2上。除非我在这里遗漏了什么,否则这要归结为创建Func解析器的实例,这正是我首先要解决的问题。我不能让t作为泛型。@liho1eye:是的,你可以-你只需要用泛型来做那部分。我保留您的非泛型API,因为您将返回一个ParseHandler,但您将通过方法中的反射使用泛型。@Jon我仍然感到困惑。。。如何从MethodInfo实例到BuildParseHandler?@liho1eye:现在已编辑,但我需要让孩子们准备好睡觉,所以我需要一段时间才能再次作出响应。