Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#调用时,通用静态调用错误_C#_.net_Extension Methods - Fatal编程技术网

C#调用时,通用静态调用错误

C#调用时,通用静态调用错误,c#,.net,extension-methods,C#,.net,Extension Methods,我有一个通用扩展方法,如下所示: public static class Validator { public static IEnumerable<string> Validate<T>(IList<T> items) { foreach (var item in items) { var result = MyValidator.Validate(item);

我有一个通用扩展方法,如下所示:

public static class Validator
{
    public static IEnumerable<string> Validate<T>(IList<T> items)
    {
        foreach (var item in items)
        {
            var result = MyValidator.Validate(item);

            if (!result.Any()) continue;
            
            foreach (var validationResult in result)
                yield return validationResult.ErrorMessage;

        }
    }
    
    public static IEnumerable<string> Validate<T>(T item)
    {
            var result = MyValidator.Validate(item);

            if (!result.Any()) yield break;
            
            foreach (var validationResult in result)
                yield return validationResult.ErrorMessage;

    }
}
公共静态类验证程序
{
公共静态IEnumerable验证(IList项)
{
foreach(项目中的var项目)
{
var result=MyValidator.Validate(项目);
如果(!result.Any())继续;
foreach(结果中的var validationResult)
产生返回validationResult.ErrorMessage;
}
}
公共静态IEnumerable验证(T项)
{
var result=MyValidator.Validate(项目);
如果(!result.Any())产生中断;
foreach(结果中的var validationResult)
产生返回validationResult.ErrorMessage;
}
}
但是当我为单个对象或集合调用方法时,它调用Validate(T item)

var item=newperson();
var items=新列表();
var v1=验证器。验证(项目);//调用验证(T项)
var v2=验证器。验证(项目);//调用Validate(T项),但应调用Validate(IList项)
我想调用
Validate(IList项)
查看列表


出现此问题的原因?

这些扩展方法具有相似的签名-
IList项
T项


Validate(IList项)
重命名为
ValidateList(IList项)
或将
Validate(T项)
重命名为
ValidateItem(T项)
将提供您要查找的结果。

这是因为接口在重载解析中的优先级低于具体类型
正如@JonSkeet指出的,这可能是因为从
T
T
的类型转换比从
List
IList
的类型转换更好,所以编译器选择泛型重载

在您的例子中,您可以通过将方法的参数从
IList
更改为
List
来获得所需的行为

公共接口IFoo{}
公共类Foo:IFoo{}
公共静态类验证器
{
公共静态void方法(T){}
公共静态void方法(对象o){}
公共静态无效方法(IFoo i){}
}
静态void Main()
{
var foo=new foo();
方法(foo);//调用方法(T)
对象o=foo;
方法(o);//显式对象,调用方法(对象o)
IFoo i=foo;
方法(i);//显式接口,调用方法(ifooi)
}

var v1=Validator.Validate(新列表(){item});它不是一个扩展方法,除非您将它的第一个参数声明为
this IList items
,而且,您似乎有一个递归<代码>验证(T项)调用自身:
item.Validate()
。由于
T
没有通用约束,
Validate
不能是
项的成员。这是否回答了您的问题?我建议将其中一种方法重命名,最好是将列表的方法重命名为类似于
ValidateList
的方法。这不是原因,请参阅建议的副本。名称相同但参数不同“这是因为接口在重载解析中的优先级低于具体类型。”不,这不是事实。这是因为在对第一个方法的调用中,转换是从
List
IList
;第二个是从
T
T
。后者是首选的,因为类型是相同的-如果
items
已声明为
IList
,则将使用第一种方法。@JonSkeet如果我不准确,很抱歉,您是否有解释解决方案的文档链接?我找不到,所以我测试了我的假设shown@JonSkeet将方法声明为
Validate(IList items)
似乎无法战胜
Validate(t item)
,而
Validate(List items)
则是。是的,但这并不是因为
IList
是一个接口<代码>验证(对象)
的工作方式也一样。基本上,有关重载解析和“更好的转换”一节中的语言规范中都有详细说明。
var item = new Person();
var items = new List<Person>();

var v1 = Validator.Validate(item);  // calls Validate<T>(T item)
var v2 = Validator.Validate(items); // calls Validate<T>(T item) but should call Validate<T>(IList<T> items)