【问题标题】:Implicit cast fails for myClass<T> when T is IEnumerable<U>当 T 为 IEnumerable<U> 时,myClass<T> 的隐式转换失败
【发布时间】:2012-09-02 21:35:30
【问题描述】:

我知道并且我想我了解 IEnumerables 的 (co/conta)variance 问题。但是我认为下面的代码不会受到它的影响。

[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; }
}

这个类是为了模仿 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);
    }
}

它工作正常,但是下面的代码给出了一个错误

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);
    }
}

错误在哪里

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?)

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

【问题讨论】:

    标签: c# .net .net-3.5


    【解决方案1】:

    啊,你被 C# 语言规范的一个不太明显的限制挫败了。

    对于给定的源类型 S 和目标类型 T,如果 S 或 T 可以为空 类型,让 S0 和 T0 引用它们的底层类型,否则 S0 和 T0 分别等于 S 和 T。允许使用类或结构 仅声明从源类型 S 到目标类型 T 的转换 如果以下所有条件都为真:

    ·S0和T0是不同的类型。

    · S0 或 T0 是类或结构类型,其中 发生运算符声明。

    · S0 和 T0 都不是接口类型。

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

    现在,这似乎并不适用,因为您的隐式转换函数需要一个泛型参数,但这个限制似乎同样适用于用作泛型参数的类型。我拿了你的例子,把IEnumerable改成了List(一个完整的类型,而不仅仅是一个接口),它编译没有错误。

    长话短说,您只需将任何返回接口类型的表达式包装在 WcfResult 构造函数中,因为它无法使用隐式转换。

    return new WcfResult<IEnumerable<Client>>(Client.GetClients(clientSearcher, LdapHelper, 100));
    

    【讨论】:

    • WTF...这就是为什么我无法在我的机器上重现 OP 的问题,我正在使用 Foo&lt;List&lt;A&gt;&gt; 进行测试!
    猜你喜欢
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多