2009-12-28 8 views
7

Tworzyłem operator konwersji jawnej, który konwertuje między ogólną listą typów jednostek na ogólną listę typów modeli. Czy ktoś wie, dlaczego pojawia się następujący błąd:Błąd operatora konwersji jednoznacznej podczas konwertowania ogólnych list

User-defined conversion must convert to or from the enclosing type

mam już jawnego operatora konwersji pomiędzy Entity.objA i Model.objA które działa prawidłowo. Problem pojawia się podczas próby przekształcenia ogólnej listy. Czy to możliwe?

Oto mój kod:

public static explicit operator List<Model.objA>(List<Entity.objA> entities) 
    { 
     List<Model.objA> objs= new List<Model.objA>(); 
     foreach (Entity.objA entity in entities) 
     { 
      objs.Add((Model.objA)entity); 
     } 
     return claims; 
    } 

Dzięki za wszelką pomoc.

Odpowiedz

17

Błąd "Konwersja zdefiniowana przez użytkownika musi zostać przekształcona w typ otaczający lub z niego" mówi dokładnie, co to znaczy. Jeśli masz operator konwersji

class MyClass { 
    public static explicit operator xxx(string s) { // details } 
    public static implicit operator string(xxx x) { // details } 
} 

Następnie xxx musi być MyClass. To właśnie oznacza "konwersja musi zostać przekształcona do typu zamkniętego lub z niego". Typ otaczający to MyClass.

Odpowiedni odcinek ECMA334 C# spec 17.9.4:

A conversion operator converts from a source type, indicated by the parameter type of the conversion operator, to a target type, indicated by the return type of the conversion operator. 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, where S0 and T0 are the types that result from removing the trailing ? modifiers, if any, from S and T:

S0 and T0 are different types.

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

Neither S0 nor T0 is an interface-type.

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

Więc oto kod:

public static explicit operator List<Model.objA>(List<Entity.objA> entities) { 
    List<Model.objA> objs= new List<Model.objA>(); 
    foreach (Entity.objA entity in entities) { 
     objs.Add((Model.objA)entity); 
    } 
    return claims; 
} 

Problem jest, że do tego, aby być zdefiniowane jako operator konwersji to musi znajdować się w klasach List<Model.objA> lub List<Entity.objA>, ale oczywiście nie możesz tego zrobić, ponieważ nie masz dostępu do zmiany tych typów.

Można użyć Enumerable.Select do projekcji na inny typ lub List<T>.ConvertAll. Na przykład:

public static class ListExtensions { 
    public static List<Model.objA> ConvertToModel(this List<Entity.objA> entities) { 
     return entities.ConvertAll(e => (Model.objA)e); 
    } 
} 
2

Zasadniczo nie można tego zrobić. W twoim operatorze typ wejścia lub wyjścia musi być typu deklarującego operatora. Jedna opcja może być metodą rozszerzającą, ale szczerze mówiąc LINQ Select przychodzi dość blisko, podobnie jak List<T>.ConvertAll.

Jako przykład tego podejścia metodę rozszerzenia:

public static class MyListUtils { 
    public static List<Model.objA> ToModel(this List<Entity.objA> entities) 
    { 
    return entities.ConvertAll(entity => (Model.objA)entity); 
    } 
} 

lub bardziej ogólnie z LINQ Select:

public static class MyListUtils { 
    public static IEnumerable<Model.objA> ToModel(
    this IEnumerable<Entity.objA> entities) 
    { 
    return entities.Select(entity => (Model.objA)entity); 
    } 
} 

i wystarczy użyć someList.ToModel().

Powiązane problemy