IEnumerable에 항목을 추가하는 방법 수집?
위의 제목으로 내 질문입니다. 예를 들어
IEnumerable<T> items = new T[]{new T("msg")};
items.ToList().Add(new T("msg2"));
그러나 결국에는 1 개의 항목 만 있습니다.
우리는 같은 방법을 가질 수 있습니까 items.Add(item)
?
같은 List<T>
IEnumerable<T>
항목을 추가 할 수있는 컬렉션을 반드시 나타내지는 않기 때문에 할 수 없습니다 . 사실, 반드시 컬렉션을 나타내는 것은 아닙니다! 예를 들면 다음과 같습니다.
IEnumerable<string> ReadLines()
{
string s;
do
{
s = Console.ReadLine();
yield return s;
} while (s != "");
}
IEnumerable<string> lines = ReadLines();
lines.Add("foo") // so what is this supposed to do??
그러나 당신이 할 수있는 일은 열거되지 않은 이전 IEnumerable
객체의 모든 항목과 자신의 일부를 제공하는 지정되지 않은 유형 의 새 객체를 만드는 것입니다. 당신은 그것을 위해 사용 Enumerable.Concat
합니다 :
items = items.Concat(new[] { "foo" });
이렇게 하면 배열 객체가 변경되지 않습니다 (어쨌든 배열에 항목을 삽입 할 수 없음). 그러나 배열의 모든 항목을 나열한 다음 "Foo"를 나열하는 새 객체를 만듭니다. 또한이 새 객체는 배열의 변경 사항을 추적합니다 (즉, 열거 할 때마다 항목의 현재 값이 표시됨).
유형 IEnumerable<T>
이 이러한 작업을 지원하지 않습니다. IEnumerable<T>
인터페이스 의 목적은 소비자가 컬렉션의 내용을 볼 수 있도록하는 것입니다. 값을 수정하지 마십시오.
.ToList (). Add ()와 같은 작업을 수행하면 새 List<T>
목록을 만들고 해당 목록에 값을 추가합니다. 원래 목록에 연결되어 있지 않습니다.
할 수있는 작업은 확장 추가 방법을 사용하여 추가 IEnumerable<T>
된 값으로 새로 작성하는 것 입니다.
items = items.Add("msg2");
이 경우에도 원본 IEnumerable<T>
객체 는 수정되지 않습니다 . 참조를 보유하여 확인할 수 있습니다. 예를 들어
var items = new string[]{"foo"};
var temp = items;
items = items.Add("bar");
이 작업 집합 후에도 변수 temp는 값 집합에서 단일 요소 "foo"를 가진 열거 형 만 참조하지만 항목은 "foo"및 "bar"값을 가진 다른 열거 형을 참조합니다.
편집하다
나는 Add가 일반적인 확장 방법이 아니라는 것을 잊어 버렸 IEnumerable<T>
습니다. 여기있어
public static IEnumerable<T> Add<T>(this IEnumerable<T> e, T value) {
foreach ( var cur in e) {
yield return cur;
}
yield return value;
}
ICollection<T>
또는 IList<T>
인터페이스를 대신 사용해 보셨습니까? 또는 에 Add
메소드 를 사용하려는 이유가 있습니다 IEnumerable<T>
.
IEnumerable<T>
실제 기본 개체가 항목 추가 / 제거를 지원하는지 여부를 반드시 보장하지 않고 유형을 '잘 표시, 열거 가능 또는 일련의 항목으로'표시 '하는 데 사용됩니다. 또한 이러한 인터페이스는 구현 IEnumerable<T>
되어 있으므로 모든 확장 방법을 사용할 수 IEnumerable<T>
있습니다.
몇 가지 짧고 달콤한 확장 방법이 IEnumerable
있고 IEnumerable<T>
나를 위해합니다.
public static IEnumerable Append(this IEnumerable first, params object[] second)
{
return first.OfType<object>().Concat(second);
}
public static IEnumerable<T> Append<T>(this IEnumerable<T> first, params T[] second)
{
return first.Concat(second);
}
public static IEnumerable Prepend(this IEnumerable first, params object[] second)
{
return second.Concat(first.OfType<object>());
}
public static IEnumerable<T> Prepend<T>(this IEnumerable<T> first, params T[] second)
{
return second.Concat(first);
}
우아함 (비 제네릭 버전 제외). 이 방법이 BCL에없는 것이 너무 나쁩니다.
IEnumerable은 항목 추가를 지원하지 않습니다.
'대체'는 다음과 같습니다.
var List = new List(items);
List.Add(otherItem);
.net Core Enumerable.Append
에는 정확히 그렇게 하는 방법 이 있습니다.
메소드의 소스 코드는 GitHub에서 사용할 수 있습니다. .... 구현 (다른 답변의 제안보다 더 정교함)은 가치가 있습니다. :).
두 번째 메시지를 추가하려면-
IEnumerable<T> items = new T[]{new T("msg")};
items = items.Concat(new[] {new T("msg2")})
상태와 같은 항목을 추가 할 수있을뿐만 아니라 List<T>
기존 열거자가 있는 항목 (또는 거의 다른 비 읽기 전용 컬렉션)에 항목을 추가 하면 열거자가 무효화됩니다 ( InvalidOperationException
그때부터 던져 집니다).
일부 유형의 데이터 쿼리에서 결과를 집계하는 경우 Concat
확장 방법을 사용할 수 있습니다 .
편집 : 원래 Union
예제 에서 확장명을 사용했지만 실제로는 올바르지 않습니다. 내 응용 프로그램은 광범위하게 사용하여 겹치는 쿼리가 결과를 복제하지 않도록합니다.
IEnumerable<T> itemsA = ...;
IEnumerable<T> itemsB = ...;
IEnumerable<T> itemsC = ...;
return itemsA.Concat(itemsB).Concat(itemsC);
Enumerable.Concat
확장 방법 외에도 Enumerable.Append
.NET Core 1.1.1에 다른 방법이있는 것 같습니다 . 후자는 단일 항목을 기존 순서에 연결할 수 있습니다. 따라서 Aamol의 답변은 다음과 같이 쓸 수도 있습니다.
IEnumerable<T> items = new T[]{new T("msg")};
items = items.Append(new T("msg2"));
여전히이 함수는 입력 시퀀스를 변경하지 않으며 주어진 시퀀스와 추가 된 항목을 함께 묶는 래퍼 만 반환합니다.
다른 사람들은 이미 아이템을 추가 할 수없는 이유에 대해 이미 설명했습니다 IEnumerable
. 컬렉션을 나타내는 인터페이스로 코딩을 계속하고 add 메소드를 원한다면 ICollection
또는로 코딩해야한다고 덧붙일 것 IList
입니다. 추가 된 보난자로서 이러한 인터페이스는를 구현 IEnumerable
합니다.
당신은 이것을 할 수 있습니다.
//Create IEnumerable
IEnumerable<T> items = new T[]{new T("msg")};
//Convert to list.
List<T> list = items.ToList();
//Add new item to list.
list.add(new T("msg2"));
//Cast list to IEnumerable
items = (IEnumerable<T>)items;
가장 쉬운 방법은 간단합니다.
IEnumerable<T> items = new T[]{new T("msg")};
List<string> itemsList = new List<string>();
itemsList.AddRange(items.Select(y => y.ToString()));
itemsList.Add("msg2");
그런 다음 IEnumerable 인터페이스를 구현하기 때문에 IEnumerable로 목록을 반환 할 수 있습니다
물론, 가능합니다 (T-business를 제쳐두고 있습니다) :
public IEnumerable<string> tryAdd(IEnumerable<string> items)
{
List<string> list = items.ToList();
string obj = "";
list.Add(obj);
return list.Select(i => i);
}
참고 URL : https://stackoverflow.com/questions/1210295/how-can-i-add-an-item-to-a-ienumerablet-collection
'Programming' 카테고리의 다른 글
GitHub 프로젝트에서 README와 README.md의 차이점은 무엇입니까? (0) | 2020.02.26 |
---|---|
CLR에서 'as'키워드를 사용하여 캐스팅 (0) | 2020.02.26 |
기능이 조기에 종료 되었습니까? (0) | 2020.02.26 |
STA와 MTA를 설명해 주시겠습니까? (0) | 2020.02.25 |
PostgreSQL에서 읽기 전용 사용자를 어떻게 만듭니 까? (0) | 2020.02.25 |