[c#] IEnumerable <T>에서 ICollection <T>로 변환 할 수 없습니다.

다음을 정의했습니다.

public ICollection<Item> Items { get; set; }

이 코드를 실행할 때 :

Items = _item.Get("001");

다음과 같은 메시지가 나타납니다.

Error   3
Cannot implicitly convert type
'System.Collections.Generic.IEnumerable<Storage.Models.Item>' to
'System.Collections.Generic.ICollection<Storage.Models.Item>'.
An explicit conversion exists (are you missing a cast?)

누군가 내가 뭘 잘못하고 있는지 설명 할 수 있습니까? Enumerable, Collections 및 ToList () 사용의 차이점에 대해 매우 혼란 스럽습니다.

추가 된 정보

나중에 내 코드에 다음이 있습니다.

for (var index = 0; index < Items.Count(); index++)

Items를 IEnumerable로 정의해도됩니까?



답변

ICollection<T>IEnumerable<T>그래서에서 상속 하여 결과를 할당합니다.

IEnumerable<T> Get(string pk)

ICollection<T>두 가지 방법이있다.

// 1. You know that the referenced object implements `ICollection<T>`,
//    so you can use a cast
ICollection<T> c = (ICollection<T>)Get("pk");

// 2. The returned object can be any `IEnumerable<T>`, so you need to 
//    enumerate it and put it into something implementing `ICollection<T>`. 
//    The easiest is to use `ToList()`:
ICollection<T> c = Get("pk").ToList();

두 번째 옵션은 더 유연하지만 성능에 훨씬 더 큰 영향을 미칩니다. 또 다른 옵션은 인터페이스에서 IEnumerable<T>추가 된 추가 기능이 필요하지 않은 경우 결과를로 저장하는 것 ICollection<T>입니다.

추가 성능 설명

당신이 가지고있는 루프

for (var index = 0; index < Items.Count(); index++)

작동 IEnumerable<T>하지만 비효율적입니다. 에 대한 각 호출 Count()에는 모든 요소 의 완전한 열거 가 필요합니다 . 컬렉션 및 Count속성 (괄호 제외)을 사용하거나 foreach 루프로 변환합니다.

foreach(var item in Items)


답변

당신은 직접 변환 할 수 없습니다 IEnumerable<T>ICollection<T>. 의 ToList방법을 사용 IEnumerable<T>하여 변환 할 수 있습니다.ICollection<T>

someICollection = SomeIEnumerable.ToList();


답변

질문에 대한 추가 정보 보류 중 :

항목 유형 및 Get의 서명에 대한 자세한 정보를 제공하십시오.

시도 할 수있는 두 가지 방법은 다음과 같습니다.

  • _item.Get의 반환 값을 (ICollection)으로 캐스팅하려면
  • 두 번째로 _item.Get ( “001”). ToArray () 또는 _item.Get ( “001”). ToList ()를 사용합니다.

두 번째는 어레이 복사본에 대한 성능 저하가 발생합니다. Get의 서명 (반환 유형)이 ICollection이 아니면 첫 번째가 작동하지 않고 IEnumerable이 아니면 두 번째가 작동하지 않습니다.


질문과 의견에 대한 설명에 따라 _item.Get ( “001”) 반환 유형을 ICollection에 개인적으로 선언합니다. 즉, 불필요한 생성 / 복사 작업을 수반하는 캐스팅이나 변환 (ToList / ToArray를 통해)을 수행 할 필요가 없습니다.

// Leave this the same
public ICollection<Item> Items { get; set; }

// Change function signature here:
// As you mention Item uses the same underlying type, just return an ICollection<T>
public ICollection<Item> Get(string value);

// Ideally here you want to call .Count on the collectoin, not .Count() on 
// IEnumerable, as this will result in a new Enumerator being created 
// per loop iteration
for (var index = 0; index < Items.Count(); index++)

친애하는,


답변