2009-12-28 19 views
7

Sto creando un operatore di conversione esplicito per convertire tra un elenco generico di tipi di entità in un elenco generico di tipi di modello. Qualcuno sa perché ottengo il seguente errore:Errore esplicito dell'operatore di conversione durante la conversione di elenchi generici

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

Ho già un operatore di conversione esplicito tra Entity.objA e Model.objA che funziona bene. Il problema sorge quando provi a convertire la lista generica. È possibile?

Ecco il mio codice:

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

Grazie per qualsiasi aiuto.

risposta

17

L'errore "Conversione definita dall'utente deve convertire in o dal tipo di chiusura" dice esattamente cosa significa. Se si dispone di un operatore di conversione

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

Poi xxx deve essere MyClass. Questo è ciò che si intende per "la conversione deve essere convertita in o dal tipo di chiusura". Il tipo di allegato qui è MyClass.

La sezione dedicata del 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.

Quindi, ecco il codice:

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

Il problema è che per questo deve essere definito come un operatore di conversione è deve risiedere nelle classi List<Model.objA> o List<Entity.objA> ma ovviamente non è possibile farlo poiché non si ha accesso per modificare tali tipi.

È possibile utilizzare Enumerable.Select per proiettare sull'altro tipo o List<T>.ConvertAll. Ad esempio:

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

Fondamentalmente, non è possibile farlo. Nell'operatore, il tipo di input o output deve essere del tipo che dichiara l'operatore. Un'opzione potrebbe essere un metodo di estensione, ma per essere onesto LINQ Select si avvicina molto da solo, così come lo è List<T>.ConvertAll.

Come esempio dell'approccio metodo di estensione:

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

o più in generale con LINQ Select:

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

e basta usare someList.ToModel().

Problemi correlati