来自Action< T>的类型参数不能被推断,但是来自Func< T>可 [英] type argument from Action<T> cannot be inferred, but from Func<T> can be

查看:124
本文介绍了来自Action< T>的类型参数不能被推断,但是来自Func< T>可的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在玩泛型和代表,我发现了一些我不明白的东西。我有非常类似的通用静态方法,一个接受 Action< T> ,第二个接受 Func< T> 。现在的问题是:如果我调用那个接受 Func< T> 而不显式Type,编译器就可以了。但是,一个接受 Action< T> 的程序无法编译(请参阅错误消息的代码)。



我的问题是:为什么编译器能够识别返回类型,但是不能识别参数类型?

  public界面IMessage 
{}

public class消息:IMessage
{
}





  static void HandleAction< TMessage>(Action< TMessage> action)
其中TMessage:IMessage
{}

static void HandleFunction< TMessage>(Func< TMessage> action)
其中TMessage:IMessage
{}

static void A (消息消息)
{}

静态消息F()
{
返回新消息();
}

static void Main(string [] args)
{
//这一个可以
HandleFunction(F);

//编译器错误:
//方法的类型参数
//'template_test.Program.HandleAction< TMessage>(System.Action< TMessage>)'
//不能从使用推断出来。
//尝试显式指定类型参数。
// HandleAction(A);

//这一个是ok
HandleAction< Message>(A);
}

我在Visual Studio 2012中使用.NET 4.5。

解决方案

方法可以通过参数重载,所有重载都由一个方法组组成,例如 void Xyz(int i) void Xyz(string s)在同一方法组内,名为 Xyz 。即使用户仅定义一种方法,编译器也无法扣除一些参数,因为编译器的行为相当严格。



返回类型不能重载方法,所以你不能在同一个类中有 int Xyz() string Xyz()返回类型可以被编译器轻松扣除,因为没有重载。



这对我来说不是第一次,但是在我意识到我可以创建一个超负荷。


I've been playing a little with generics and delegates and I have found something I don't understand. I have quite similar generic static methods, one accepts Action<T> and the second one accepts Func<T>. Now the problem: if I call the one accepting Func<T> without explicit Type, compiler is fine with that. But with the one accepting Action<T> my program can't be compiled (see the code for error message).

My question is: Why is compiler able to recognize return type, but is not able to recognize argument type?

public interface IMessage
{ }

public class Message : IMessage
{
}

static void HandleAction<TMessage>(Action<TMessage> action)
    where TMessage : IMessage
{ }

static void HandleFunction<TMessage>(Func<TMessage> action)
    where TMessage : IMessage
{ }

static void A(Message message)
{ }

static Message F()
{
    return new Message();
}

static void Main(string[] args)
{
    // this one is ok
    HandleFunction(F);

    // compiler error:
    // The type arguments for method
    // 'template_test.Program.HandleAction<TMessage>(System.Action<TMessage>)' 
    // cannot be inferred from the usage.
    //Try specifying the type arguments explicitly.
    //HandleAction(A);

    // this one is ok
    HandleAction<Message>(A);
}

I'm using .NET 4.5 in Visual Studio 2012.

解决方案

Methods can be overloaded by their arguments and all overloads form one method group, so for example void Xyz(int i) and void Xyz(string s) are within same method group called Xyz. Compiler is not able to deduct a type of argument even if user defines only one method, because behaviour of compiler is quite strict.

Methods can't be overloaded by return types, so you can't have int Xyz() and string Xyz() within same class. Return type can be deducted by compiler easily, because there is no overloading.

It was not obvious for me for the first time, but it has been quite clear after I realized that I could create an overload.

这篇关于来自Action&lt; T&gt;的类型参数不能被推断,但是来自Func&lt; T&gt;可的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆