gpt4 book ai didi

c# - 接口(interface)的扩展方法是否被视为比不太具体的方法优先级低?

转载 作者:可可西里 更新时间:2023-11-01 08:48:45 24 4
gpt4 key购买 nike

我有以下扩展类:

public static class MatcherExtensions
{
public static ExecMatcher<T1, T2> Match<T1, T2>(this Tuple<T1, T2> item)
{
return new ExecMatcher<T1, T2>(item.Item1, item.Item2);
}

public static ExecMatcher<T1, T2> Match<T1, T2>(this ITupleMatchable<T1, T2> item)
{
var tuple = item.PropertiesToMatch;
return new ExecMatcher<T1, T2>(tuple.Item1, tuple.Item2);
}

public static ExecMatcher<T> Match<T>(this T item) { return new ExecMatcher<T>(item); }
}

如果我创建一个元组并调用 Match() ,它正确地使用了第一种扩展方法:

var tuple = Tuple.Create(1, "a");
tuple.Match().With(1, "a")... // compiles just fine.

如果我创建一个 int 并调用 Match() ,它正确地使用了最后一个扩展方法:

var one = 1;
one.Match().With(1)... // compiles just fine.

但是,如果我创建 SomeClass , 它实现了 ITupleMatchable<int, string>并尝试匹配它,编译器仍然选择第三种扩展方法,而不是第二种,尽管后者是更具体的匹配:

var obj = new SomeClass(1, "a");
obj.Match().With(1, "a")... // won't compile.

基于 Eric Lippert's answer to a similar question ,我通过将第三个扩展方法放入子目录中它自己的类中来解决这个问题,从而创建了一个更长的命名空间,因此它与调用代码之间的“距离”比特定于 ITupleMatchable<T1, T2> 的版本更大。 .不过,这对我来说就像一个 hack。有没有更简洁的方法来解决这个问题?

最佳答案

如果你简单地使用 new SomeClass(1, "a")ITupleMatchable<int, string> ,它将正常工作:

var obj = (ITupleMatchable<int, string>)new SomeClass(1, "a");
obj.Match().With(1, "a");

请记住,您的 obj否则变量的编译时类型为 SomeClass .与必须查看 SomeClass 的接口(interface)实现相比,编译器可以“更容易地”将实际类与第三个扩展方法(与任何 类型兼容)相匹配。然后将其匹配到例如第二种扩展方法。

但如果您提供 this参数作为实际的接口(interface)类型,那么第二个扩展方法更合适,因为它正是方法正在寻找的类型,而不是更广泛的“任何类型”。 IE。这是一个更具体的声明,“更好”也是如此。

请注意,一旦找到候选扩展方法集(通过与命名空间相关的规则等),实际方法将使用正常的重载决策来确定。 IE。在您的 MatcherExtensions 中确定了至少一种方法class 是一个符合条件的扩展方法,然后编译器会按照正常的重载解析规则从中进行选择。您可以在 C# 5.0 规范的 7.5.3 部分找到这些规则.

但简而言之:在应用重载决议规则之前(实际上,为了确定哪些方法甚至符合条件),请注意编译器已经决定了泛型类型参数。因此,在评估重载决议时,它正在查看 Match(SomeClass item)。和 Match(ITupleMatchable<int, string> item) .希望一旦你考虑到这一点,你就会明白为什么,如果变量的类型是 SomeClass , 编译器优先选择你的第三个扩展而不是第二个,反之亦然,如果类型是 ITupleMatchable<int, string> .

关于c# - 接口(interface)的扩展方法是否被视为比不太具体的方法优先级低?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31345843/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com