2009-12-28 41 views
7

我正在創建一個顯式轉換運算符,以將實體類型的通用列表轉換爲模型類型的通用列表。有誰知道爲什麼我收到以下錯誤:在轉換通用列表時顯式轉換運算符錯誤

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

我已經有Entity.objA和Model.objA之間的顯式轉換運算符,它工作正常。嘗試轉換通用列表時出現問題。這甚至有可能嗎?

這裏是我的代碼:

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

感謝您的幫助。

回答

17

錯誤「用戶定義的轉換必須轉換爲封閉類型或從封閉類型轉換」正是這個意思。如果你有一個轉換操作符

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

然後xxx必須MyClass。這就是「轉換必須轉換爲封閉類型或從封閉類型轉換」的含義。這裏的封閉類型是MyClass

的ECMA334 C#規範的相關章節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.

因此,這裏是你的代碼:

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

的問題是,這個被定義爲一個轉換操作符它必須位於List<Model.objA>List<Entity.objA>類中,但當然由於您無權更改這些類型,因此您無法這樣做。

您可以使用Enumerable.Select投影到另一種類型或List<T>.ConvertAll。例如:

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

基本上,你不能這樣做。在您的操作員中,輸入或輸出類型必須是聲明操作員的類型。一種選擇可能是擴展方法,但說實話,LINQ Select本身非常接近,List<T>.ConvertAll也是如此。

作爲擴展方法的方法的一個示例:

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

或更一般地與LINQ Select

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

,只是使用someList.ToModel()