当T是IEnumerable <U>时,myClass <T>的隐式强制转换失败

Sco*_*ain 6 .net c# .net-3.5

我知道并且我认为我理解IEnumerables 的(co/conta)方差问题.但是我认为以下代码不会受到影响.

[DataContract]
public class WcfResult<T>
{
    public WcfResult(T result)
    {
        Result = result;
    }

    public WcfResult(Exception error)
    {
        Error = error;
    }

    public static implicit operator WcfResult<T>(T rhs)
    {
        return new WcfResult<T>(rhs);
    }

    [DataMember]
    public T Result { get; set; }
    [DataMember]
    public Exception Error { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这个类是模仿BackgroundWorker的RunWorkerCompletedEventArgs所以我可以从我的WCF服务返回错误而不会导致连接错误.

我的大多数代码工作正常,所以我可以做这样的事情

public WcfResult<Client> AddOrUpdateClient(Client client)
{
    try
    {
        //AddOrUpdateClient returns "Client"
        return client.AddOrUpdateClient(LdapHelper);
    }
    catch (Exception e)
    {
        return new WcfResult<Client>(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

并且它工作正常,但是下面的代码会出错

public WcfResult<IEnumerable<Client>> GetClients(ClientSearcher clientSearcher)
{
    try
    {
        //GetClients returns "IEnumerable<Client>"
        return Client.GetClients(clientSearcher, LdapHelper, 100);
    }
    catch (Exception e)
    {
        return new WcfResult<IEnumerable<Client>>(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

错误在哪里

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<myNs.Client>'
to 'myNs.WcfResult<System.Collections.Generic.IEnumerable<myNs.Client>>'. An explicit
conversion exists (are you missing a cast?)
Run Code Online (Sandbox Code Playgroud)

导致此错误发生的错误是什么?

Ada*_*ras 7

啊,你被C#语言规范的一个不那么明显的限制所挫败了.

对于给定的源类型S和目标类型T,如果S或T是可空类型,则让S 0和T 0引用它们的基础类型,否则S 0和T 0分别等于S和T. 仅当满足以下所有条件时,才允许类或结构声明从源类型S到目标类型T的转换:

·S 0和T 0是不同的类型.

·S 0或T 0是发生运算符声明的类或结构类型.

· S 0和T 0都不是接口类型.

·排除用户定义的转换,从S到T或从T到S不存在转换.

现在,似乎这不适用,因为您的隐式转换函数采用泛型参数,但此限制似乎同样适用于用作泛型参数的类型.我把你的榜样,改变IEnumerableList(全型,不只是一个接口),它编译无误.

简而言之,您只需要在WcfResult构造函数中包装任何返回接口类型的表达式,因为隐式转换将不可用.

return new WcfResult<IEnumerable<Client>>(Client.GetClients(clientSearcher, LdapHelper, 100));
Run Code Online (Sandbox Code Playgroud)