c# – 泛型扩展方法歧义

c# – 泛型扩展方法歧义,第1张

概述我有两个接口定义: // IVector.cspublic interface IVector{ int Size { get; } float this[int index] { get; set; }}// IMatrix.cspublic interface IMatrix{ int Size { get; } float this[int 我有两个接口定义:
// IVector.cspublic interface IVector{    int Size { get; }    float this[int index] { get; set; }}// IMatrix.cspublic interface IMatrix{    int Size { get; }    float this[int row,int column] { get; set; }}
@H_502_4@以及这些接口的扩展方法

// VectorExtensions.cspublic static T Add<T>(this T vector,T value) where T : struct,IVector{    var output = default(T);    for (int i = 0; i < output.Size; i++)        output[i] = vector[i] + value[i];    return output;}// MatrixExtensions.cspublic static T Add<T>(this T matrix,IMatrix{    var output = default(T);    for (int i = 0; i < output.Size; i++)        for (int j = 0; j < output.Size; j++)            output[i,j] = vector[i,j] + value[i,j];    return output;}
@H_502_4@所有类型都在同一个命名空间中.

@H_502_4@由于某些原因,当从IVector派生的东西调用Add()时,编译器无法确定是使用MatrixExtensions类还是VectorExtensions类中的定义.将其中一个扩展类移动到另一个命名空间停止错误…但是我希望它们在同一个命名空间中:D

@H_502_4@为什么会发生这种情况?

@H_502_4@编辑:(我不敢相信我忘了添加这个)
为了解决这个问题我该怎么办?

解决方法 您有两个扩展方法,每个方法具有相同的签名.
// VectorExtensions.cspublic static T Add<T>(this T vector,T value)// MatrixExtensions.cs public static T Add<T>(this T matrix,T value)
@H_502_4@是的,你在你的代码中提供了约束,但是constraints are not part of the signature.所以你有两个方法具有相同的签名,所以这两种方法都不比其他方法更好,而且你有歧义的问题.

@H_502_4@将静态扩展方法类中的一个移动到不同的命名空间中的原因是不同的结果是编译器将在扩展搜索外部之前首先在最接近的包含命名空间中寻找扩展方法匹配. (参见C#语言规范的第7.5.5.2节[如下])如果将MatrixExtensions移动到另一个命名空间中,则原始命名空间内的扩展方法调用将明确地解析为VectorExtensions方法,因为它是最接近命名空间.但是,这并不能完全解决您的问题.因为如果它是最接近的扩展方法,因此您仍然可以使用这个VectorExtensions实现方法,因为再次约束不是签名的一部分.

@H_502_4@为方便起见,语言规范.

@[email protected] Extension method invocations

@H_502_4@In a method invocation (§7.5.5.1) of
one of the forms

@H_502_4@expr . IDentifIEr ( )

@H_502_4@expr . IDentifIEr ( args )

@H_502_4@expr . IDentifIEr < typeargs > ( )

@H_502_4@expr . IDentifIEr < typeargs > ( args )

@H_502_4@if the normal processing of the
invocation finds no applicable
methods,an attempt is made to process
the construct as an extension method
invocation. The objective is to find
the best type-name C,so that the
corresponding static method invocation
can take place:

@H_502_4@C . IDentifIEr ( expr )

@H_502_4@C . IDentifIEr ( expr,args )

@H_502_4@C . IDentifIEr < typeargs > ( expr )

@H_502_4@C . IDentifIEr < typeargs > ( expr,args )

@H_502_4@The search for C proceeds as follows:

@H_502_65@Starting with the closest enclosing namespace declaration,continuing with
each enclosing namespace declaration,
and ending with the containing
compilation unit,successive attempts
are made to find a candIDate set of
extension methods: @H_502_65@If the given namespace or compilation unit directly contains
non-generic type declarations Ci with
extension methods Mj that have the
name IDentifIEr and are accessible and
applicable with respect to the desired
static method invocation above,then
the set of those extension methods is
the candIDate set. @H_502_65@If namespaces imported by using namespace directives in the given
namespace or compilation unit directly
contain non-generic type declarations
Ci with extension methods Mj that have
the name IDentifIEr and are accessible
and applicable with respect to the
desired static method invocation
above,then the set of those extension
methods is the candIDate set. @H_502_65@If no candIDate set is found in any enclosing namespace declaration or
compilation unit,a compile-time error
occurs. @H_502_65@Otherwise,overload resolution is applIEd to the candIDate set as
described in (§7.4.3). If no single
best method is found,a compile-time
error occurs. @H_502_65@C is the type within which the best method is declared as an extension method. Using C as a target,the method call is then processed as a static method invocation (§7.4.4). 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
总结

以上是内存溢出为你收集整理的c# – 泛型扩展方法歧义全部内容,希望文章能够帮你解决c# – 泛型扩展方法歧义所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/1261550.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存