2009-12-28 4 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 } 
} 

이있는 경우 다음 xxxMyClass을해야합니다. 이것은 "변환이 반드시 둘러싸는 유형으로 변환되어야합니다"라는 의미입니다. 여기에 묶는 유형은 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 SelectList<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()를 사용한다.