【问题标题】:type argument from Action<T> cannot be inferred, but from Func<T> can be无法推断来自 Action<T> 的类型参数,但可以推断来自 Func<T>
【发布时间】:2014-03-26 18:28:56
【问题描述】:

我一直在玩一些泛型和委托,但我发现了一些我不理解的东西。我有非常相似的通用静态方法,一个接受Action&lt;T&gt;,第二个接受Func&lt;T&gt;。现在的问题是:如果我在没有明确类型的情况下调用接受Func&lt;T&gt; 的那个,编译器就可以了。但是如果接受Action&lt;T&gt;,我的程序将无法编译(请参阅错误消息代码)。

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

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);
}

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

【问题讨论】:

标签: c# generics delegates


【解决方案1】:

方法可以通过它们的参数重载,所有重载形成一个方法组,例如void Xyz(int i)void Xyz(string s) 位于称为Xyz 的同一个方法组中。即使用户只定义了一个方法,编译器也无法推断出一种类型的参数,因为编译器的行为非常严格。

方法不能被返回类型重载,所以你不能在同一个类中拥有int Xyz()string Xyz()。编译器可以很容易地推断出返回类型,因为没有重载。

第一次对我来说不是很明显,但是当我意识到我可以创建一个重载之后就很清楚了。

【讨论】:

  • 所以只有 Function Name 没有指定参数类型可能是模棱两可的。
  • @jayatubi 正确。
猜你喜欢
  • 1970-01-01
  • 2014-12-27
  • 1970-01-01
  • 1970-01-01
  • 2020-07-05
  • 2019-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多