에 대한 AddRange()
방법 이 없습니다 IList<T>
.
항목을 IList<T>
반복하고 Add()
메서드를 사용하지 않고 항목 목록을에 추가하려면 어떻게 해야합니까?
에 대한 AddRange()
방법 이 없습니다 IList<T>
.
항목을 IList<T>
반복하고 Add()
메서드를 사용하지 않고 항목 목록을에 추가하려면 어떻게 해야합니까?
답변:
AddRange
정의됩니다 List<T>
인터페이스가 아니라 있습니다.
에 대한 액세스 권한을 얻기 위해 List<T>
대신 변수를 선언 IList<T>
하거나 캐스트 할 List<T>
수 있습니다 AddRange
.
((List<myType>)myIList).AddRange(anotherList);
int로서 이것은 좋은 방법 (아래 설명 참조)없는 IList<T>
힘이 되지 수 List<T>
있지만, 인터페이스를 구현하고 매우가 없습니다 수있는 몇 가지 다른 종류의 AddRange
코드가를 throw 할 때와 같은 경우에, 당신은 발견 할 것이다 - 방법 런타임에 예외입니다.
따라서 유형이 실제로 a라는 List<T>
것을 확실히 알지 못하는 한 AddRange
.
이를 수행하는 한 가지 방법은 is 또는 as 연산자를 사용하여 형식을 테스트하는 것입니다 (C # 7부터).
if(myIList is List<T>)
{
// can cast and AddRange
}
else
{
// iterate with Add
}
List<T>
하는 것이 좋을 것입니다 (또는 이것이 당신에게 좋은 선택이 아니라면, AddRange
지역화를 유지 해야하는 곳에서 캐스트를하십시오 -이것은 매우 저렴한 작업입니다.) ).
InvalidCastException
이외에서 사용하는 경우 List<T>
(예를 들어, 배열).
List 에 대한 C # 소스 코드를 보면 보면 List.AddRange ()에 간단한 루프가 해결하지 못하는 최적화가 있다고 생각합니다. 따라서 확장 메서드는 IList가 List인지 확인하고, 그렇다면 기본 AddRange ()를 사용해야합니다.
소스 코드를 살펴보면 .NET 사용자가 .ToList ()와 같은 작업을 위해 자체 Linq 확장에서 유사한 작업을 수행하는 것을 볼 수 있습니다 (목록 인 경우 캐스트 ... 그렇지 않으면 생성).
public static class IListExtension
{
public static void AddRange<T>(this IList<T> list, IEnumerable<T> items)
{
if (list == null) throw new ArgumentNullException(nameof(list));
if (items == null) throw new ArgumentNullException(nameof(items));
if (list is List<T> asList)
{
asList.AddRange(items);
}
else
{
foreach (var item in items)
{
list.Add(item);
}
}
}
}
list
에서 List<T>
두 번 캐스팅 하고 있습니다. 그중 하나는 as
키워드 로 최적화 할 수 있습니다 .
if (list is List<T> castedList) { castedList.AddRange(items); }
다음과 같이 할 수 있습니다.
IList<string> oIList1 = new List<string>{"1","2","3"};
IList<string> oIList2 = new List<string>{"4","5","6"};
IList<string> oIList3 = oIList1.Concat(oIList2).ToList();
그래서, 기본적으로는 사용하는 것이 Concat()
확장과 ToList()
같은 유사한 기능을 얻을 AddRange()
.
Enumerable.Concat
는에 의해 구현되고 System.Linq.Enumerable
해당 메서드의 반환 값이 IEnumerable<TSource>
이므로 다시 캐스팅해서는 안된다고 생각합니다 IList<TSource>
. 소스 코드를 확인하지 않고는 알 수없는 구현 세부 정보로 인해 다른 것을 반환 할 수 있습니다. 하지만 변경되지 않을 것이라는 보장은 없습니다. 따라서 여러 .NET 버전을 지원할 때는 특별한주의를 기울여야합니다.
다음과 같은 확장 메서드를 작성할 수도 있습니다.
internal static class EnumerableHelpers
{
public static void AddRange<T>(this IList<T> collection, IEnumerable<T> items)
{
foreach (var item in items)
{
collection.Add(item);
}
}
}
용법:
IList<int> collection = new int[10]; //Or any other IList
var items = new[] {1, 4, 5, 6, 7};
collection.AddRange(items);
여전히 항목에 대해 반복되지만 호출 할 때마다 반복을 작성하거나 캐스팅 할 필요가 없습니다.
Concat
@Self_Taught_Programmer 가 대답 했듯이 LINQ를 캐스팅하거나 사용하십시오 .