隐式转换对委托类型推断的意外影响 [英] Unexpected effect of implicit cast on delegate type inference

查看:107
本文介绍了隐式转换对委托类型推断的意外影响的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 Money 类型,含有 decimal 的隐式转换:

I have a simple Money type with an implicit cast from decimal:

struct Money
{
    decimal innerValue;
    public static implicit operator Money(decimal value)
    {
        return new Money { innerValue = value };
    }
    public static explicit operator decimal(Money value)
    {
        return value.innerValue;
    }

    public static Money Parse(string s)
    {
        return decimal.Parse(s);
    }
}

我定义了一个 Sum ()重载以对这些值进行操作:

And I defined a Sum() overload to operate on those values:

static class MoneyExtensions
{
    public static Money Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, Money> selector)
    {
        return source.Select(x => (decimal)selector(x)).Sum();
    }
}

我没想到这个扩展方法干扰现有的 Sum()扩展方法:

What I didn't expect was for this extension method to interfere with the existing Sum() extension methods:

var source = new[] { "2" };
Money thisWorks = source.Sum(x => Money.Parse(x));
int thisWorksToo = source.Sum(new Func<string, int>(x => int.Parse(x)));
int thisDoesNot = source.Sum(x => int.Parse(x));

错误是不能将类型Money隐式转换为int,显式转换你错过了一个演员吗?)。编译器支持 int =>是正确的decimal =>

The error is "Cannot implicitly convert type 'Money' to 'int'. An explicit conversion exists (are you missing a cast?)". Is it correct that the compiler favors int => decimal => Money implicit conversions over resolving an overload that's an exact match?

推荐答案

从C#4.0规范中,第7.6.5.2节:

From the C# 4.0 Specification, section 7.6.5.2:


上述规则意味着实例方法优先于扩展方法,内部命名空间声明中可用的扩展方法优先在外部命名空间声明中可以使用超扩展方法,并且直接在命名空间中声明的扩展方法优先于使用using命名空间指令导入到同一命名空间的扩展方法

The preceding rules mean that instance methods take precedence over extension methods, that extension methods available in inner namespace declarations take precedence over extension methods available in outer namespace declarations, and that extension methods declared directly in a namespace take precedence over extension methods imported into that same namespace with a using namespace directive

这可能是导致您的Money Sum扩展方法优先于Linq的 - 这就是为什么你没有得到一个模糊的方法调用错误。

Probably, this is causing your Money Sum extension method to take precedence over the ones from Linq - that's why you don't get an "ambiguous method call" error.

这篇关于隐式转换对委托类型推断的意外影响的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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