隐式转换失败MyClass的< T>当T的IEnumerable< U>隐式、MyClass、LT、GT

2023-09-03 07:05:33 作者:普通朋友

我知道,我想我明白有关(CO / CONTA)方差问题IEnumerables。不过,我认为下面的code不会受到它的影响。

I know and I think I understand about the (co/conta)variance issue with IEnumerables. However I thought the following code would not be affected by it.

[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服务返回错误而不断裂的连接。

This class is to mimic BackgroundWorker's RunWorkerCompletedEventArgs so I can return errors from my WCF service without faulting the connection.

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

Most of my code is working fine so I can do things like this

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

和它工作正常,但如下因素code给出了一个错误

and it works fine, however the folowing code gives a error

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

这是怎么回事错误是导致发生这种错误?

What is going wrong that is causing this error to happen?

推荐答案

嗯,你已经挫败了C#语言规范的低于明显的限制。

Ah, you've been foiled by a less-than-obvious restriction of the C# Language Specification.

对于给定的源类型S和目标类型T,如果S或T是可以为null   类型,令S 0 和T 0 指他们的基本类型,否则小号 0 和   牛逼 0 分别等于S和T。类或结构允许   声明从源类型S转换到目标类型T只   如果满足以下所有条件都为真:

For a given source type S and target type T, if S or T are nullable types, let S0 and T0 refer to their underlying types, otherwise S0 and T0 are equal to S and T respectively. A class or struct is permitted to declare a conversion from a source type S to a target type T only if all of the following are true:

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

· S0 and T0 are different types.

·S与 0 或T 0 是类或结构类型,其中,   运算符声明发生。

· Either S0 or T0 is the class or struct type in which the operator declaration takes place.

无论小号 0 和T 0 是一个接口类型。

· Neither S0 nor T0 is an interface-type.

·不包括用户自定义的转换,转换不   存在从S到T或从T到秒。

· Excluding user-defined conversions, a conversion does not exist from S to T or from T to S.

现在,它似乎并不像这将适用,因为你的隐式转换函数有一个通用的参数,但这一限制似乎适用于一样多作为一般的参数类型。我把你的榜样,改变了的IEnumerable 列表(一个完整的类型,而不是只是一个接口),并没有错误编译

Now, it doesn't seem like this would apply because your implicit conversion function takes a generic parameter, but this restriction seems to apply to types used as generic arguments just as much. I took your example and changed IEnumerable to List (a full type, not just an interface) and it compiled without error.

为了使长话短说,你只需将需要包装任何EX pression返回在 WcfResult 构造接口类型,因为隐式转换将无法使用它。

To make a long story short, you're simply going to need to wrap any expression that returns an interface type in the WcfResult constructor, because the implicit cast won't be available for it.

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