隐式和显式委托创建之间的区别(有和没有泛型)

The difference between implicit and explicit delegate creation (with and without generics)(隐式和显式委托创建之间的区别(有和没有泛型))
本文介绍了隐式和显式委托创建之间的区别(有和没有泛型)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请看下面 Go() 方法中的四行代码:

delegate void Action<T>(T arg);
delegate void Action();

void DoSomething<T>(Action<T> action)
{
    //...
}

void DoSomething(Action action)
{
    //...
}

void MyAction<T>(T arg)
{
    //...
}

void MyAction()
{
    //...
}

void Go<T>()
{
    DoSomething<T>(MyAction<T>); // throws compiler error - why?
    DoSomething(new Action<T>(MyAction<T>)); // no problems here
    DoSomething(MyAction); // what's the difference between this...
    DoSomething(new Action(MyAction)); // ... and this?
}

请注意,第一次调用产生的编译器错误是:方法Action(T)"的类型参数不能从用法中推断出来.尝试明确指定类型参数.

Note that the compiler error generated by the first call is: The type arguments for method 'Action(T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

推荐答案

MyActionnew Action(MyAction) 没有区别(当它们都有效时)除了前者之外,在 C# 1 中不起作用.这是一个隐式方法组转换.有时这不适用,尤其是当编译器无法确定您想要什么样的委托时,例如

There's no difference between MyAction and new Action(MyAction) (when they're both valid) other than the former won't work in C# 1. This is an implicit method group conversion. There are times that this isn't applicable, most notable when the compiler can't work out what kind of delegate you want, e.g.

Delegate foo = new Action(MyAction); // Fine
Delegate bar = MyAction; // Nope, can't tell target type

这在您的问题中起作用,因为所涉及的两种方法都已重载.这基本上会导致头痛.

This comes into play in your question because both of the methods involved are overloaded. This leads to headaches, basically.

至于泛型方面 - 这很有趣.方法组并没有从 C# 3 类型推断中得到太多的喜爱——我不确定这是否会在 C# 4 中得到改进.如果您调用泛型方法并指定类型参数,则类型推断工作得相当好 - 但如果您尝试反过来做,它会失败:

As for the generics side - it's interesting. Method groups don't get much love from C# 3 type inference - I'm not sure whether that's going to be improved in C# 4 or not. If you call a generic method and specify the type argument, type inference works fairly well - but if you try to do it the other way round, it fails:

using System;

class Test
{
    static void Main()
    {
        // Valid - it infers Foo<int>
        DoSomething<int>(Foo);
        // Valid - both are specified
        DoSomething<int>(Foo<int>);
        // Invalid - type inference fails
        DoSomething(Foo<int>);
        // Invalid - mismatched types, basically
        DoSomething<int>(Foo<string>);
    }

    static void Foo<T>(T input)
    {
    }

    static void DoSomething<T>(Action<T> action)
    {
        Console.WriteLine(typeof(T));
    }
}

C# 3 中的类型推断非常复杂,在大多数情况下都能很好地工作(特别是它对 LINQ 非常有用),但在其他一些情况下却失败了.在理想的世界中,它会变得更容易理解并且在未来的版本中会更强大......我们拭目以待!

Type inference in C# 3 is very complicated, and works well in most cases (in particular it's great for LINQ) but fails in a few others. In an ideal world, it would become easier to understand and more powerful in future versions... we'll see!

这篇关于隐式和显式委托创建之间的区别(有和没有泛型)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)