위의 제목으로 내 질문. 예를 들어
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 (!string.IsNullOrEmpty(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에없는 것이 너무 나쁩니다.
답변
.net Core Enumerable.Append
에는 정확히 그렇게 하는 방법 이 있습니다.
메소드의 소스 코드는 GitHub에서 사용할 수 있습니다. …. 구현 (다른 답변의 제안보다 더 정교함)은 가치가 있습니다 :).
답변
IEnumerable은 항목 추가를 지원하지 않습니다.
‘대체’는 다음과 같습니다.
var List = new List(items);
List.Add(otherItem);
답변
두 번째 메시지를 추가하려면-
IEnumerable<T> items = new T[]{new T("msg")};
items = items.Concat(new[] {new T("msg2")})