단일 항목을 IEnumerable <T>로 전달


377

매개 변수 T를 예상하는 메소드에 단일 유형의 항목을 전달하는 일반적인 방법이 IEnumerable<T>있습니까? 언어는 C #, 프레임 워크 버전 2.0입니다.

현재 도우미 메서드를 사용하고 있습니다 (.Net 2.0이므로 LINQ와 비슷한 캐스팅 / 프로젝션 도우미 메서드가 많이 있습니다). 그러나 이것은 어리석은 것처럼 보입니다.

public static class IEnumerableExt
{
    // usage: IEnumerableExt.FromSingleItem(someObject);
    public static IEnumerable<T> FromSingleItem<T>(T item)
    {
        yield return item; 
    }
}

다른 방법은 물론 만들고 채우는 것 List<T>또는를 Array하고 대신 전달할 IEnumerable<T>.

[편집] 확장 방법으로 이름을 지정할 수 있습니다 :

public static class IEnumerableExt
{
    // usage: someObject.SingleItemAsEnumerable();
    public static IEnumerable<T> SingleItemAsEnumerable<T>(this T item)
    {
        yield return item; 
    }
}

여기에 뭔가 빠졌습니까?

[Edit2] 우리는 someObject.Yield()(아래 주석에서 @Peter가 제안한 바와 같이)이 확장 방법에 가장 적합한 이름, 주로 간결성을 위해 다음과 같은 것을 발견했습니다.

public static class IEnumerableExt
{
    /// <summary>
    /// Wraps this object instance into an IEnumerable&lt;T&gt;
    /// consisting of a single item.
    /// </summary>
    /// <typeparam name="T"> Type of the object. </typeparam>
    /// <param name="item"> The instance that will be wrapped. </param>
    /// <returns> An IEnumerable&lt;T&gt; consisting of a single item. </returns>
    public static IEnumerable<T> Yield<T>(this T item)
    {
        yield return item;
    }
}

6
확장 메서드 본문에서 약간 수정했습니다. if (item == null) yield break; 이제 null 전달을 중단하고에 대한 (사소한) null 객체 패턴을 사용하지 않습니다 IEnumerable. ( foreach (var x in xs)xs을 잘 처리 합니다). 덧붙여서이 함수는 list 모나드의 모나드 단위이며 IEnumerable<T>Microsoft의 모나드 러브 페스트를 감안할 때 처음에는 프레임 워크에없는 것과 같은 것이 놀랍습니다.
매트 Enright

2
확장 메서드의 경우 해당 이름 AsEnumerable의 내장 확장이 이미 있으므로 이름을 지정 하지 않아야 합니다 . ( 예를 들어 T구현할 때 )IEnumerablestring
Jon-Eric

22
방법의 이름은 Yield어떻습니까? 간결함을 능가하는 것은 없습니다.
Philip Guin

4
여기에서 이름을 제안하십시오. "SingleItemAsEnumerable"은 조금 장황합니다. "Yield"는 인터페이스가 아닌 구현을 설명합니다. 좋지 않습니다. 더 나은 이름을 얻으려면 행동의 정확한 의미에 해당하는 "AsSingleton"을 제안합니다.
어스 엔진

4
나는 left==null수표가 싫어 . 코드의 아름다움을 깨뜨리고 코드가 더 유연 해지지 않습니다. 언젠가 널이 될 수있는 무언가로 싱글 톤을 생성해야하는 경우는 어떻습니까? 내 말은와 new T[] { null }동일하지 않으며 new T[] {}언젠가는 구별해야 할 수도 있습니다.
어스 엔진

답변:


100

도우미 방법은 IMO를 수행하는 가장 깨끗한 방법입니다. 목록이나 배열을 전달하면 부주의 한 코드 조각이이를 캐스팅하여 내용을 변경하여 일부 상황에서 이상한 동작을 일으킬 수 있습니다. 읽기 전용 컬렉션을 사용할 수 있지만 더 많은 줄 바꿈이 필요할 수 있습니다. 귀하의 솔루션은 최대한 깔끔하다고 생각합니다.


목록 / 배열이 임시로 구축 된 경우, 그 범위는 메소드 호출 후에 종료되므로 문제를 일으키지 않아야합니다.
Mario F

배열로 보내면 어떻게 변경할 수 있습니까? 배열에 캐스트 할 수 있다고 생각한 다음 다른 것으로 참조를 변경하지만 어떻게하면 좋을까요? (아마도 뭔가
빠졌을

2
두 개의 다른 메소드에 전달하기 위해 열거 가능한 것을 작성하기로 결정했다고 가정하십시오. 첫 번째 메소드는 배열로 캐스팅하고 내용을 변경했습니다. 그런 다음 변경 사항을 알지 못하고 다른 메소드에 인수로 전달합니다. 나는 그것이 필요하지 않을 때 변경 가능한 것을 갖는 것이 naturla 불변성보다 덜 깔끔하다는 것을 말하지는 않습니다.
Jon Skeet

3
이것은 받아 들여지는 대답이며 대부분 읽을 가능성이 높으므로 여기에 내 관심사를 추가 할 것입니다. 이 방법을 시도했지만 이전에 컴파일하는 호출 유형 이 myDict.Keys.AsEnumerable()어디 인지 파산했습니다 . 확장 메서드의 이름을 로 바꾸면 모든 것이 작동하기 시작했습니다. IEnumerable <Dictionary <CheckBox, System.Tuple <int, int >>. KeyCollection> '을'IEnumerable <CheckBox> '로 변환 할 수 없습니다. 명시적인 변환이 존재합니다 (캐스트가 없습니까?) 잠시 동안 해킹을 할 수 있지만 다른 파워 해커가 더 나은 방법을 찾을 수 있습니까? myDictDictionary<CheckBox, Tuple<int, int>>SingleItemAsEnumerable
Hamish Grubijan

3
@HamishGrubijan : 처음 dictionary.Values부터 시작한 것처럼 들립니다 . 기본적으로 무슨 일이 일어나고 있는지 명확하지 않지만 새로운 질문을 시작하는 것이 좋습니다.
Jon Skeet

133

글쎄, 메소드 IEnumerable가 하나의 요소 만 포함하더라도 목록 인 것을 전달해야한다고 기대 한다면.

통과

new[] { item }

논쟁이 충분해야한다고 생각합니다


32
: 나는 그것이 추정되기 때문에 (P 내가 여기 아주 잘못된 생각하지 않는 한) 당신도의 T 드롭 것 같아
Svish

2
C # 2.0에서는 유추되지 않은 것 같습니다.
Groo

4
"언어는 C #, 프레임 워크 버전 2입니다."C # 3 컴파일러는 T를 유추 할 수 있으며 코드는 .NET 2와 완벽하게 호환됩니다.
sisve

가장 좋은 대답은 바닥에 있습니까?!
Falco Alexander

2
@Svish 난 그냥 그렇게 할 수있는 답변을 제안하고 편집-우리는 지금 2020에있어 "표준"imho해야합니다
OschtärEi

120

C # 3.0에서는 System.Linq.Enumerable 클래스를 활용할 수 있습니다.

// using System.Linq

Enumerable.Repeat(item, 1);

그러면 아이템 만 포함하는 새로운 IEnumerable이 생성됩니다.


26
이 솔루션으로 코드를 읽기가 더 어렵다고 생각합니다. :( 단일 요소에 대한 반복은 매우 반 직관적이라고 생각하지 않습니까?
Drahakar

6
한 번 반복해서 나에게 확인을 읽습니다. 또 다른 확장 방법을 추가하고 네임 스페이스가 사용되는 곳마다 포함되도록 보장 할 필요없이 훨씬 간단한 솔루션입니다.
si618

13
그래, 나는 실제로 new[]{ item }나 자신을 사용 하고, 나는 그것이 흥미로운 해결책이라고 생각했다.
luksan

7
이 솔루션은 돈입니다.
ProVega

IMHO 이것은 정답입니다. 읽기 쉽고 간결하며 사용자 지정 확장 방법없이 BCL에서 한 줄로 구현됩니다.
라이언

35

C # 3 (2라고 말했듯이)에서 구문을 좀 더 수용 할 수있는 일반적인 확장 방법을 작성할 수 있습니다.

static class IEnumerableExtensions
{
    public static IEnumerable<T> ToEnumerable<T>(this T item)
    {
        yield return item;
    }
}

클라이언트 코드는 item.ToEnumerable()입니다.


고마워, 나는 그것을 알고 있습니다 (C # 3.0을 사용하면 .Net 2.0에서 작동합니다), 이것에 대한 내장 메커니즘이 있는지 궁금합니다.
Groo

12
이것은 정말 좋은 대안입니다. 난 그냥 ToEnumerable엉망을 피하기 위해 이름 바꾸기를 제안하고 싶습니다System.Linq.Enumerable.AsEnumerable
Fede

3
참고로에 대한 ToEnumerable확장 메소드 가 이미 있으므로이 IObservable<T>메소드 이름은 기존 규칙을 방해합니다. 솔직히, 나는 그것의 간단하기 때문에, 전혀 확장 방법을 사용하지 않는 게 좋을 것 너무 일반적인.
cwharris 2016

14

이 헬퍼 메소드는 항목 또는 다수에 적용됩니다.

public static IEnumerable<T> ToEnumerable<T>(params T[] items)
{
    return items;
}    

1
하나 이상의 항목을 지원하므로 유용한 변형입니다. params배열을 빌드하는 데 의존 하므로 결과 코드가 깨끗합니다. new T[]{ item1, item2, item3 };여러 항목 보다 더 선호하는지 여부를 결정하지 않았습니다 .
ToolmakerSteve

똑똑한 ! 그것을 사랑
후루타 미쓰루

10

클라이언트 API를 단순화하기 위해 T 유형의 인수로 메소드의 새로운 과부하를 제안한 사람이 아무도 없습니다.

public void DoSomething<T>(IEnumerable<T> list)
{
    // Do Something
}

public void DoSomething<T>(T item)
{
    DoSomething(new T[] { item });
}

이제 클라이언트 코드는 다음과 같이 할 수 있습니다.

MyItem item = new MyItem();
Obj.DoSomething(item);

또는 목록 :

List<MyItem> itemList = new List<MyItem>();
Obj.DoSomething(itemList);

19
더 좋은 점 DoSomething<T>(params T[] items)은 컴파일러가 단일 항목에서 배열로의 변환을 처리한다는 의미입니다. (이것은 또한 여러 개의 개별 항목을 전달할 수있게하며, 컴파일러는 다시 배열로 변환하는 것을 처리합니다.)
LukeH

7

(이전에 말했듯이)

MyMethodThatExpectsAnIEnumerable(new[] { myObject });

또는

MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(myObject, 1));

참고로, 익명 객체의 빈 목록을 원할 경우 마지막 버전도 좋습니다.

var x = MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(new { a = 0, b = "x" }, 0));

Enumerable.Repeat는 .Net 3.5의 새로운 기능이지만 감사합니다. 위의 도우미 방법과 유사한 것으로 보입니다.
Groo

7

방금 찾은 사용자 LukeH가 제안한 것을 보았 듯이이 작업을 수행하는 좋은 간단한 방법은 다음과 같습니다.

public static void PerformAction(params YourType[] items)
{
    // Forward call to IEnumerable overload
    PerformAction(items.AsEnumerable());
}

public static void PerformAction(IEnumerable<YourType> items)
{
    foreach (YourType item in items)
    {
        // Do stuff
    }
}

이 패턴을 사용하면 여러 가지 방법으로 동일한 기능을 호출 할 수 있습니다. 단일 항목; 여러 항목 (쉼표로 구분); 배열; 목록; 열거 등

그래도 AsEnumerable 메서드를 사용하는 효율성에 대해서는 100 % 확신 할 수 없지만 잘 작동합니다.

업데이트 : AsEnumerable 기능이 매우 효율적으로 보입니다! ( 참고 )


실제로는 전혀 필요하지 않습니다 .AsEnumerable(). 배열은 YourType[]이미 구현했습니다 IEnumerable<YourType>. 그러나 내 질문은 두 번째 방법 (예 :) 만 사용할 수 있고 .NET 2.0을 사용하고 단일 항목을 전달하려는 경우를 언급하고있었습니다.
Groo

2
그렇습니다. 그러나 스택 오버플로가 발생할 수 있습니다 ;-)
teppicymon

그리고 실제로 당신의 실제 질문에 대답하기 위해서 (실제로 내가 대답하고자하는 질문이 아닙니다!) 마리오의 답변에 따라 배열로 변환해야합니다
teppicymon

2
IEnumerable<T> MakeEnumerable<T>(params T[] items) {return items;}메소드를 정의하는 것은 어떻습니까? 그런 다음 IEnumerable<T>원하는 수의 개별 항목에 대해을 ( 를) 예상 한대로 사용할 수 있습니다. 코드는 기본적으로 단일 항목을 반환하는 특수 클래스를 정의하는 것만 큼 효율적이어야합니다.
supercat

6

한 가지 방법으로는 너무 과잉이지만 일부 사람들은 Interactive Extensions가 유용하다고 생각합니다.

Microsoft의 대화식 확장 (Ix)에는 다음 방법이 포함됩니다.

public static IEnumerable<TResult> Return<TResult>(TResult value)
{
    yield return value;
}

다음과 같이 활용할 수 있습니다.

var result = EnumerableEx.Return(0);

Ix는 원래 Linq 확장 방법에없는 새로운 기능을 추가하며 Rx (Reactive Extensions)를 생성 한 직접적인 결과입니다.

Linq Extension Methods+ Ix= Rx용으로 생각하십시오 IEnumerable.

CodePlex에서 Rx와 Ix를 모두 찾을 수 있습니다 .


5

이 30 % 더 빠른 것보다 yieldEnumerable.Repeat에 사용하는 경우 foreach로 인해 이 C # 컴파일러 최적화 하고, 다른 경우에는 동일한 성능의.

public struct SingleSequence<T> : IEnumerable<T> {
    public struct SingleEnumerator : IEnumerator<T> {
        private readonly SingleSequence<T> _parent;
        private bool _couldMove;
        public SingleEnumerator(ref SingleSequence<T> parent) {
            _parent = parent;
            _couldMove = true;
        }
        public T Current => _parent._value;
        object IEnumerator.Current => Current;
        public void Dispose() { }

        public bool MoveNext() {
            if (!_couldMove) return false;
            _couldMove = false;
            return true;
        }
        public void Reset() {
            _couldMove = true;
        }
    }
    private readonly T _value;
    public SingleSequence(T value) {
        _value = value;
    }
    public IEnumerator<T> GetEnumerator() {
        return new SingleEnumerator(ref this);
    }
    IEnumerator IEnumerable.GetEnumerator() {
        return new SingleEnumerator(ref this);
    }
}

이 테스트에서 :

    // Fastest among seqs, but still 30x times slower than direct sum
    // 49 mops vs 37 mops for yield, or c.30% faster
    [Test]
    public void SingleSequenceStructForEach() {
        var sw = new Stopwatch();
        sw.Start();
        long sum = 0;
        for (var i = 0; i < 100000000; i++) {
            foreach (var single in new SingleSequence<int>(i)) {
                sum += single;
            }
        }
        sw.Stop();
        Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
        Console.WriteLine($"Mops {100000.0 / sw.ElapsedMilliseconds * 1.0}");
    }

고마워,이 경우에 대한 구조체를 만들어 루프 루프에서 GC 부담을 줄이십시오.
Groo

1
열거 자와 열거 가능한 모두 반환되면 상자에 넣게됩니다 ....
Stephen Drew

2
스톱워치를 사용하여 비교하지 마십시오. Benchmark.NET 사용 github.com/dotnet/BenchmarkDotNet
NN_

1
방금 측정하면 new [] { i }옵션이 옵션보다 약 3.2 배 빠릅니다. 또한 옵션은로 확장하는 것보다 약 1.2 배 빠릅니다 yield return.
lorond

다른 C # 컴파일러 최적화를 사용 하여이 속도를 높일 수 있습니다 : SingleEnumerator GetEnumerator()구조체를 반환 하는 메서드 를 추가 하십시오. C # 컴파일러는 인터페이스 대신이 방법을 사용하여 (덕 타이핑을 통해 조회) 박스를 피합니다. 많은 내장 컬렉션이 List 와 같은이 트릭을 사용합니다 . 참고 : 이는 SingleSequence예와 같이 직접 참조가있는 경우에만 작동 합니다. IEnumerable<>변수에 저장 하면 트릭이 작동하지 않습니다 (인터페이스 방법이 사용됨)
enzi

5

IanG이 주제에 대한 좋은 게시물을 가지고 EnumerableFrom()있으며, 이름으로 제안 하고 Haskell과 Rx 가이 를 언급합니다 Return. IIRC F #은 그것을 Return이라고 부릅니다 . F # Seq은 연산자를 호출합니다singleton<'T> .

C # 중심이 될 준비가 되었다면 유혹하는 것은 그것을 실현 Yield하는 yield return데 관여한다고 주장하는 것입니다.

퍼포먼스 측면에 관심이 있다면 James Michael Hare는 0 또는 1 개의 게시물을 반환합니다 . 이는 스캔할만한 가치가 있습니다.


4

이것은 더 나을 수는 없지만 멋지다.

Enumerable.Range(0, 1).Select(i => item);

그렇지 않습니다. 그것은 다르다.
nawfal

Ewww. 항목을 열거 가능하게 만드는 것만으로도 자세한 내용입니다.
ToolmakerSteve

1
이것은 아침 식사를 만들기 위해 Rube Goldberg 기계 를 사용하는 것과 같습니다 . 예, 작동하지만 10 농구를 뛰어 넘습니다. 이와 같은 간단한 일은 수백만 번 실행되는 타이트한 루프에서 수행 될 때 성능 병목 현상이 될 수 있습니다. 실제로 성능 측면은 99 %의 경우 중요하지 않지만 개인적으로 여전히 불필요한 불필요한 과잉이라고 생각합니다.
enzi

4

원래 게시물에 대한 @EarthEngine의 의견에 동의합니다. 즉 'AsSingleton'이 더 나은 이름입니다. 이 위키 백과 항목을 참조하십시오 . 그런 다음 싱글 톤의 정의에서 null 값이 인수로 전달되면 'AsSingleton'은 빈 IEnumerable 대신 단일 null 값으로 IEnumerable을 반환해야 if (item == null) yield break;논쟁을 해결할 수 있습니다. 가장 좋은 해결책은 'AsSingleton'과 'AsSingletonOrEmpty'; 여기서 null이 인수로 전달되는 경우 'AsSingleton'은 단일 null 값을 반환하고 'AsSingletonOrEmpty'는 빈 IEnumerable을 반환합니다. 이처럼 :

public static IEnumerable<T> AsSingletonOrEmpty<T>(this T source)
{
    if (source == null)
    {
        yield break;
    }
    else
    {
        yield return source;
    }
}

public static IEnumerable<T> AsSingleton<T>(this T source)
{
    yield return source;
}

그런 다음 IEnumerable의 'First'및 'FirstOrDefault'확장 메소드와 비슷하거나 비슷합니다.


2

내가 말한 가장 쉬운 방법은 다음과 같습니다 new T[]{item};. 이를 수행 할 구문이 없습니다. 내가 생각할 수있는 가장 가까운 것은 params키워드이지만 물론 메소드 정의에 액세스해야하며 배열에서만 사용할 수 있습니다.


2
Enumerable.Range(1,1).Select(_ => {
    //Do some stuff... side effects...
    return item;
});

위의 코드는 다음을 사용할 때 유용합니다

var existingOrNewObject = MyData.Where(myCondition)
       .Concat(Enumerable.Range(1,1).Select(_ => {
           //Create my object...
           return item;
       })).Take(1).First();

위의 코드 스 니펫에는 빈 / null 검사가 없으며 예외를 두려워하지 않고 하나의 객체 만 반환되도록 보장합니다. 또한 게으 르기 때문에 기준에 맞는 기존 데이터가 없음이 입증 될 때까지 클로저가 실행되지 않습니다.


이 답변은 자동으로 "낮은 품질"로 태그되었습니다. 도움말에 설명 된대로 ( "Brevity는 수용 가능하지만 자세한 설명이 더 낫습니다.") OP가 자신의 잘못, 코드에 대해 알려주도록 수정하십시오.
Sandra Rossi

응답하는 부분을 포함 하여이 답변의 대부분이 나중에 다른 사람이 편집 한 것으로 보입니다. 경우 두 번째 조각의 의도는 기본값을 제공하는 경우 그러나 MyData.Where(myCondition)빈, 즉 이미와 가능 (간단)입니다 DefaultIfEmpty(): var existingOrNewObject = MyData.Where(myCondition).DefaultIfEmpty(defaultValue).First();. 사용자 정의 값이 아닌 var existingOrNewObject = MyData.FirstOrDefault(myCondition);원하는 경우 더 단순화 할 수 있습니다 default(T).
BACON

0

나는 파티에 조금 늦었지만 어쨌든 내 길을 공유 할 것입니다. 내 문제는 ItemSource 또는 WPF TreeView를 단일 개체에 바인딩하려고한다는 것입니다. 계층 구조는 다음과 같습니다.

프로젝트> 도표> 방

항상 하나의 프로젝트 만 있었지만 제안 된 것처럼 하나의 객체 만 포함 된 컬렉션을 전달하지 않고도 트리에 프로젝트를 표시하고 싶었습니다.
IEnumerable 객체 만 ItemSource로 전달할 수 있으므로 클래스 IEnumerable을 만들기로 결정했습니다.

public class ProjectClass : IEnumerable<ProjectClass>
{
    private readonly SingleItemEnumerator<AufmassProjekt> enumerator;

    ... 

    public IEnumerator<ProjectClass > GetEnumerator() => this.enumerator;

    IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}

그리고 그에 따라 내 자신의 열거자를 만듭니다.

public class SingleItemEnumerator : IEnumerator
{
    private bool hasMovedOnce;

    public SingleItemEnumerator(object current)
    {
        this.Current = current;
    }

    public bool MoveNext()
    {
        if (this.hasMovedOnce) return false;
        this.hasMovedOnce = true;
        return true;
    }

    public void Reset()
    { }

    public object Current { get; }
}

public class SingleItemEnumerator<T> : IEnumerator<T>
{
    private bool hasMovedOnce;

    public SingleItemEnumerator(T current)
    {
        this.Current = current;
    }

    public void Dispose() => (this.Current as IDisposable).Dispose();

    public bool MoveNext()
    {
        if (this.hasMovedOnce) return false;
        this.hasMovedOnce = true;
        return true;
    }

    public void Reset()
    { }

    public T Current { get; }

    object IEnumerator.Current => this.Current;
}

이것은 아마도 "가장 깨끗한"해결책은 아니지만 나를 위해 일했습니다.

편집 @ Groo가 지적한 것처럼 단일 책임 원칙
을 유지하기 위해 새로운 래퍼 클래스를 만들었습니다.

public class SingleItemWrapper : IEnumerable
{
    private readonly SingleItemEnumerator enumerator;

    public SingleItemWrapper(object item)
    {
        this.enumerator = new SingleItemEnumerator(item);
    }

    public object Item => this.enumerator.Current;

    public IEnumerator GetEnumerator() => this.enumerator;
}

public class SingleItemWrapper<T> : IEnumerable<T>
{
    private readonly SingleItemEnumerator<T> enumerator;

    public SingleItemWrapper(T item)
    {
        this.enumerator = new SingleItemEnumerator<T>(item);
    }

    public T Item => this.enumerator.Current;

    public IEnumerator<T> GetEnumerator() => this.enumerator;

    IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}

내가 이렇게 사용

TreeView.ItemSource = new SingleItemWrapper(itemToWrap);

편집 2
나는 MoveNext()방법 으로 실수를 수정했습니다 .


SingleItemEnumerator<T>클래스는 의미가 있지만, 클래스는 "단일 항목 만들기 IEnumerable자체의"단일 책임 원칙의 위반처럼 보인다. 아마도 그것을 전달하는 것이 더 실용적이지만 필자는 필요에 따라 포장하는 것을 선호합니다.
Groo

0

" 좋은 솔루션 일 필요는 없지만 여전히 솔루션"또는 "최고의 LINQ 트릭"에 제출하려면 다음 Enumerable.Empty<>()과 결합 할 수 있습니다 Enumerable.Append<>().

IEnumerable<string> singleElementEnumerable = Enumerable.Empty<string>().Append("Hello, World!");

... 또는 Enumerable.Prepend<>()...

IEnumerable<string> singleElementEnumerable = Enumerable.Empty<string>().Prepend("Hello, World!");

후자의 두 가지 방법은 .NET Framework 4.7.1 및 .NET Core 1.0부터 사용할 수 있습니다.

이 하나 인 경우에 실행 가능한 솔루션입니다 정말 기존의 방법을 사용하는 대신에이보다 더 많거나 적은 분명 만약 내가 미정 해요 불구하고, 자신의 작성에 의도 솔루션 . 이것은 확실히 더 긴 코드이며 (부분적으로 유형 매개 변수 유추로 인해 발생하지 않음 ) 열거 자 객체의 두 배를 만듭니다.Enumerable.Repeat<>()Empty<>()

이것을 반올림 "이 방법들이 존재한다는 것을 알고 있습니까?" 대답 Array.Empty<>()은 대신 할 수 Enumerable.Empty<>()있지만 상황을 더 좋게 만드는 주장은 어렵습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.