有没有从隐式引用转换“System.Collections.Generic.List< T>'以“T” [英] There is no implicit reference conversion from 'System.Collections.Generic.List<T>' to 'T'

查看:344
本文介绍了有没有从隐式引用转换“System.Collections.Generic.List< T>'以“T”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class Class1<T>
{
    public virtual void Update(T entity)
    {
        Update(new List<T>() { entity }); //It's failed
    }

    public virtual void Update(IEnumerable<T> entities)
    {
    }

    public virtual void Update<TSub>(TSub entity) where TSub : T
    {
    }

    public virtual void Update<TSub>(IEnumerable<TSub> entities) where TSub : T
    {
    }
}

我有一段代码。但它总是失败。

I have a piece of code. But it always failed.

如果我换成更新(新的List< T>(){实体})更新((新的List< T>(){实体})AsEnumerable())。,这将是确定

If I replaced Update(new List<T>() { entity }) by Update((new List<T>() { entity }).AsEnumerable()), it will be ok.

太,当你删除第三个方法更新和LT这将是确定; TSUB>(TSUB实体),其中TSUB::T

It will be ok too when you delete the third method Update<TSub>(TSub entity) where TSub : T.

谁能告诉我,为什么?

推荐答案

OK,让我们通过这个精心。我们有

OK, let's go through this carefully. We have

Update(new List<T>()); 

和三位候选人 - 注意,我们只关心的签名的这些候选人,所以我们将抛开返回类型和限制,这是的未签名的一部分的:

And three candidates -- note that we care only about the signatures of those candidates, so we'll strip away the return types and constraints, which are not part of the signature:

Update(IEnumerable<T> entities)
Update<U>(U entity) 
Update<V>(IEnumerable<V> entities) 

我们的首要任务是做的类型推断的这些最后两个人选。如果推断失败的话,他们是不适用的人选。

Our first task is to do type inference on those last two candidates. If inference fails then they are not applicable candidates.

考虑第二种方法

Update<U>(U entity) 

我们有类型的参数列表< T> 和形式参数 U 。因此,我们推断, U 列表< T>

We have an argument of type List<T> and a formal parameter U. Therefore we infer that U is List<T>.

考虑第三种方法:

Update<V>(IEnumerable<V> entities)

我们有类型的参数列表< T> 和类型的形式参数的IEnumerable< V> 列表< T> 工具的IEnumerable< T> 因此,我们推断,V是T.

We have an argument of type List<T> and a formal parameter of type IEnumerable<V>. List<T> implements IEnumerable<T> so we deduce that V is T.

确定,所以我们的候选名单目前包括:

OK, so our candidate list now consists of:

Update(IEnumerable<T> entities)
Update<List<T>>(List<T> entity) 
Update<T>(IEnumerable<T> entities) 

是否所有这些候选人的适用的?是。在每种情况下列表< T> 可转换为正式参数类型。我们不能排除任何人呢。

Are all of these candidates applicable? Yes. In each case List<T> is convertible to the formal parameter type. We cannot eliminate any of them yet.

现在,我们只有适用考生一定要确定哪一个是的唯一最好的的。

Now that we have only applicable candidates we must determine which one is the unique best.

我们可以立即消除第三个。第三个和第一个是在其正式的参数列表相同。 C#的规则是,当你有两个方法是在其正式的参数列表相同,其中一人到了那里自然地,其中一人通过类型替代了那里,取代一个人失去。

We can immediately eliminate the third one. The third one and the first one are identical in their formal parameter lists. The rule of C# is that when you have two methods that are identical in their formal parameter lists, and one of them got there "naturally" and one of them got there via type substitution, the substituted one loses.

我们也可以在第一时间清除之一。显然,在第二个精确匹配比第一个不精确匹配越好。

We can also eliminate the first one. Clearly the exact match in the second one is better than the inexact match in the first one.

这使得第二个为最后一个人的地位。它赢得了重载决议斗争。然后最后的验证过程中,我们发现,违反约束:列表< T> 是不能保证是一个派生类 T的

That leaves the second one as the last man standing. It wins the overload resolution fight. Then during final validation we discover that the constraint is violated: List<T> is not guaranteed to be a derived class of T.

因此​​重载解析失败。你的论点引起选为无效的最好方法

Therefore overload resolution fails. Your arguments caused the best method chosen to be invalid.

如果我称之为更新((新的List< T> (){}实体)。AsEnumerable()),这将是确定。

If I call Update((new List<T>() { entity }).AsEnumerable()), it will be ok.

正确的。通过它又来了。三位候选人:

Correct. Go through it again. Three candidates:

Update(IEnumerable<T> entities)
Update<U>(U entity) 
Update<V>(IEnumerable<V> entities) 

我们有类型的参数的IEnumerable< T> ,所以我们推断出第二和第三个是:

We have an argument of type IEnumerable<T>, so we infer the second and third to be:

Update(IEnumerable<T> entities)
Update<IEnumerable<T>>(IEnumerable<T> entity) 
Update<T>(IEnumerable<T> entities) 

现在我们有相同的参数列出了三个候选人适用。在建到了那里的人比天然的自动差,所以我们消除了第二和第三,只留下第一个。它赢了,而且它没有限制被侵犯。

Now we have three applicable candidates with identical parameter lists. The ones that got there under construction are automatically worse than the natural ones, so we eliminate the second and third, leaving only the first. It wins, and it has no constraints to be violated.

这将是也没关系,当你删除第三个方法

It will be ok too when you delete the third method

您陈述是错误的;这将产生同样的错误作为第一场景。带走了第三位候选人不会导致第一候选人突然开始跳动的第二人选。

Your statement is false; this will produce the same error as the first scenario. Taking away the third candidate does not cause the first candidate to suddenly start beating the second candidate.

这篇关于有没有从隐式引用转换“System.Collections.Generic.List&LT; T&GT;'以“T”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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