문제

위의 제목으로 내 질문. 예를 들어,

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");

이 작업 세트 후에 변수 온도는 여전히 값 세트에서 단일 요소 "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 an에 대한 방법 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 코어 1.1.1에서. 후자를 사용하면 단일 항목을 기존 시퀀스에 연결할 수 있습니다. 따라서 Aamol의 답변도 작성할 수 있습니다

IEnumerable<T> items = new T[]{new T("msg")};
items = items.Append(new T("msg2"));

그럼에도 불구 하고이 함수는 입력 시퀀스를 변경하지 않고 주어진 시퀀스와 추가 된 항목을 함께 넣는 래퍼를 반환합니다.

다른 사람들은 이미 당신이 왜 할 수 없는지에 대한 훌륭한 설명을했습니다. IEnumerable. 컬렉션을 나타내고 추가 메소드를 원하는 인터페이스로 계속 코딩하려는 경우 코드를 ICollection 또는 IList. Bonanza가 추가 된이 인터페이스는 구현됩니다 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);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top