我知道并且我认为我理解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?)
导致此错误发生的错误是什么?
答案 0 :(得分: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。
现在,似乎这不适用,因为您的隐式转换函数采用泛型参数,但此限制似乎同样适用于用作泛型参数的类型。我拿了你的例子并将IEnumerable
更改为List
(一个完整的类型,而不仅仅是一个接口)并且编译时没有错误。
总而言之,你只需要在WcfResult
构造函数中包装任何返回接口类型的表达式,因为隐式转换将不可用。
return new WcfResult<IEnumerable<Client>>(Client.GetClients(clientSearcher, LdapHelper, 100));