Implicit listing is not performed for myClass <T> when T is IEnumerable <U>

I know, and I think I understand the problem (co / conta) with IEnumerables. However, I thought the following code would not affect 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; } } 

This class should mimic BackgroundWorker RunWorkerCompletedEventArgs so that I can return errors from my WCF service without breaking the connection.

Most of my code works fine, so I can do such things

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

and it works fine, however the following code gives an 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); } } 

Where is the mistake

 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 causes this error?

+6
source share
1 answer

And, you were limited by the less obvious limitation of the C # Language Specification.

For a given type of source S and target type T, if S or T are nullable types, let S 0 and T 0 belong to their base types, otherwise S 0 and T 0 are equal to S and T, respectively. A class or structure is allowed to declare a conversion from source type S only to target type T if everything is true:

ยท S 0 and T 0 are different types.

. Any S 0 or T 0 is the type of class or structure in which the statement is operator.

ยท Neither S 0 nor T 0 is an interface.

ยท Excluding custom conversions, conversions do not exist from S to T or from T to S.

Now it doesn't seem like this is applicable, because your implicit conversion function accepts a generic parameter, but this limitation seems to apply to types used as general arguments. I took your example and changed IEnumerable to List (full type, not just an interface) and compiled without errors.

To make the long story shorter, you just need to wrap any expression that returns the interface type in the WcfResult constructor, because an implicit cast will not be available to it.

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

Source: https://habr.com/ru/post/924984/


All Articles