public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
어떻게 캐스트 List<Client>
할 수 List<IDic>
있습니까?
public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
어떻게 캐스트 List<Client>
할 수 List<IDic>
있습니까?
답변:
캐스팅 할 수 없습니다 (참조 ID 유지)-안전하지 않습니다. 예를 들면 :
public interface IFruit {}
public class Apple : IFruit {}
public class Banana : IFruit {}
...
List<Apple> apples = new List<Apple>();
List<IFruit> fruit = apples; // Fortunately not allowed
fruit.Add(new Banana());
// Eek - it's a banana!
Apple apple = apples[0];
이제 공분산으로 인해 .NET 4 / C # 4에서 a List<Apple>
로 변환 할 수 IEnumerable<IFruit>
있지만, 원하는 경우 새 목록 List<IFruit>
을 만들어야 합니다. 예를 들면 :
// In .NET 4, using the covariance of IEnumerable<T>
List<IFruit> fruit = apples.ToList<IFruit>();
// In .NET 3.5
List<IFruit> fruit = apples.Cast<IFruit>().ToList();
그러나 이것은 원래 목록을 캐스팅하는 것과 동일 하지 않습니다 . 이제 두 개의 개별 목록 이 있기 때문 입니다. 이것은 안전하지만 한 목록에 대한 변경 사항이 다른 목록에 표시되지 않음 을 이해해야 합니다. ( 물론 목록이 참조 하는 개체 에 대한 수정 사항 이 표시됩니다.)
List<IFruit>
실제로 .NET Framework에 대한 참조 인 컴파일 타임 유형의 참조가 있도록 참조를 캐스팅 할 수 있다고 가정합니다 List<Apple>
. Banana
그것에 대한 참조를 추가하면 어떤 일이 발생할 것으로 예상 List<IFruit>
합니까?
using
에 대한 지침 System.Linq
, 또는 당신이 내가 당신이 나를 도울 수있을 것으로 기대 방법이 아니에요, 그것을 호출 위해 노력하고 있습니다. 더 많은 조사를 할 것을 제안하고 여전히 막혀 있다면 최소한의 재현 가능한 예를 사용하여 질문하십시오 .
캐스트 반복기 및 .ToList () :
List<IDic> casted = input.Cast<IDic>().ToList()
트릭을 할 것입니다.
원래 저는 공분산이 효과가 있다고 말했지만 Jon이 올바르게 지적했듯이; 안돼!
그리고 원래 나도 멍청하게 ToList()
전화를 끊었 어
Cast
반환 IEnumerable<T>
하지 않습니다 List<T>
-및 아니오, 공분산 은 안전하지 않기 때문에이 변환을 허용 하지 않습니다 -내 대답을 참조하십시오.
ToList()
귀하의 의견을 읽기 전에가 누락 되었음을 깨달았습니다 . 그러나 물론 공분산은 작동하지 않습니다! 도!
Cast
.NET 4에서 형식 인수를 지정하는 한 .NET 4 에서 호출이 필요하지 않음을 의미하므로 여전히 도움이 될 수 있습니다 ToList
.
나도이 문제를했고 존 소총의 답변을 읽은 후 내가 사용하는 내 코드를 수정 List<T>
사용 IEnumerable<T>
. 이것이 OP의 원래 질문 인 How can I cast List<Client>
to에List<IDic>
대한 답변은 아니지만 그렇게 할 필요가 없으므로이 문제를 겪는 다른 사람들에게 도움이 될 수 있습니다. 물론 이것은 사용이 필요한 코드를 가정합니다.List<IDic>
귀하의 통제하에 .
예 :
public void ProcessIDic(IEnumerable<IDic> sequence)
{
// Implementation
}
대신에:
public void ProcessIDic(List<IDic> list)
{
// Implementation
}
새로 만들고 List<IDic>
모든 요소를 전송 해야만 가능 합니다.
.Net 3.5에서는 다음을 수행 할 수 있습니다.
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());
이 경우 List 생성자는 IEnumerable을 사용합니다.
목록 은 IEnumerable로만 변환 할 수 있습니다. myObj 를 ISomeInterface로 변환 할 수 있지만 IEnumerable 유형은 IEnumerable로 변환 할 수 없습니다.