重载,泛型类型推理和'参数'关键字 [英] Overloading, generic type inference and the 'params' keyword

查看:104
本文介绍了重载,泛型类型推理和'参数'关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只注意到与重载一个奇怪的行为

I just noticed a strange behavior with overload resolution.

假设我有以下方式:

public static void DoSomething<T>(IEnumerable<T> items)
{
    // Whatever

    // For debugging
    Console.WriteLine("DoSomething<T>(IEnumerable<T> items)");
}

现在,我知道,这种方法往往会使用少量的被称为明确的参数,所以为了方便我添加此过载:

Now, I know that this method will often be called with a small number of explicit arguments, so for convenience I add this overload :

public static void DoSomething<T>(params T[] items)
{
    // Whatever

    // For debugging
    Console.WriteLine("DoSomething<T>(params T[] items)");
}

现在我尝试调用这些方法:

Now I try to call these methods :

var items = new List<string> { "foo", "bar" };
DoSomething(items);
DoSomething("foo", "bar");



但在这两种情况下,用 PARAMS过载被调用。我本来期望的的IEnumerable< T> 过载的列表与LT的情况下调用; T> ,因为它似乎是一个更好的匹配(至少对我来说)。

But in both cases, the overload with params is called. I would have expected the IEnumerable<T> overload to be called in the case of a List<T>, because it seems a better match (at least to me).

这是正常的行为?谁能解释一下吗?我找不到关于在MSDN文档...什么是这里涉及的重载决议规则的任何明确的信息?

Is this behavior normal ? Could anyone explain it ? I couldn't find any clear information about that in MSDN docs... What are the overload resolution rules involved here ?

推荐答案

在C#3.0规范第7.4.3节是相关位在这里。基本参数数组扩大,所以你比较:

Section 7.4.3 of the C# 3.0 specification is the relevant bit here. Basically the parameter array is expanded, so you're comparing:

public static void DoSomething<T>(T item)

public static void DoSomething<T>(IEnumerable<T> item)



T 的第一场比赛被推断为列表<串> T 对于第二场比赛被推断为字符串

The T for the first match is inferred to be List<string> and the T for the second match is inferred to be string.

现在考虑所涉及的参数参数类型的转换。 - 在第一个它的列表<串> 列表<串> ;在第二个它的列表<串GT; 的IEnumerable<串GT; 。第一次转换是7.4.3.4比第二的规则更好。

Now consider the conversions involved for argument to parameter type - in the first one it's List<string> to List<string>; in the second it's List<string> to IEnumerable<string>. The first conversion is a better than the second by the rules in 7.4.3.4.

有悖常理位是类型推断。如果你采取的方程,它会为你期望它的工作:

The counterintuitive bit is the type inference. If you take that out of the equation, it will work as you expect it to:

var items = new List<string> { "foo", "bar" };
DoSomething<string>(items);
DoSomething<string>("foo", "bar");



在这一点上,有一个在每次通话只有一个适用的函数成员。

At that point, there's only one applicable function member in each call.

这篇关于重载,泛型类型推理和'参数'关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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