C #에서 단일 항목 목록을 만들기위한 바로 가기


134

C #에는 하나의 항목으로 List <T>를 인스턴스화하는 인라인 단축키가 있습니까?

나는 현재하고있다 :

new List<string>( new string[] { "title" } ))

이 코드를 어디에나 가지고 있으면 가독성이 떨어집니다. 나는 다음과 같은 유틸리티 방법을 사용하려고 생각했다.

public static List<T> SingleItemList<T>( T value )
{
    return (new List<T>( new T[] { value } ));
}

그래서 나는 할 수 있었다 :

SingleItemList("title");

더 짧고 깔끔한 방법이 있습니까?

감사.

답변:


245

간단히 이것을 사용하십시오 :

List<string> list = new List<string>() { "single value" };

() 중괄호를 생략 할 수도 있습니다.

List<string> list = new List<string> { "single value" };

업데이트 : 물론 이것은 둘 이상의 항목에 대해서도 작동합니다.

List<string> list = new List<string> { "value1", "value2", ... };

5
첫 번째 옵션의 괄호 안에 1 개의 리터럴을 넣으면 기본값 10이 아닌 정확히 하나의 공간에 대한 스토리지가 할당됩니다.
Joel Coehoorn

5
기본값은 4로 끝납니다. new List <string> { "Hello"} .Capacity == 4
Jon Skeet

39
var list = new List<string>(1) { "hello" };

처음에 단일 항목에 대한 공간 만 할당한다는 점을 제외하고 다른 사용자가 게시 한 내용과 매우 유사합니다.

물론 나중에 많은 것들을 추가 할 것이라는 것을 알고 있다면 좋은 생각은 아니지만 여전히 언급 할 가치가 있습니다.


용량이 1로 설정되었습니다. Jon Skeet을 포함 하여이 페이지에서 4 가지 답변에 투표했지만이 답변이 가장 정확하다고 생각합니다.
외로운 코더

28

확장 방법을 사용한다는 Michael의 생각은 훨씬 더 간단합니다.

public static List<T> InList<T>(this T item)
{
    return new List<T> { item };
}

그래서 당신은 이것을 할 수 있습니다 :

List<string> foo = "Hello".InList();

내가 좋아하는지 아닌지 잘 모르겠습니다.


1
나는 또한 내가 그것을 좋아하는지 확신하지 못한다 : 이것은 문자열 유형의 "이상한"확장이 아닌가?
M4N

1
나는 아직 당신의 책에서 확장 방법을 만들지 않았습니다. 고마워 마틴과 존.
Ryan Ische

2
@ 마틴 : 그것은 모든 유형 의 이상한 확장입니다 . 이것은 일반적으로 권장되지 않지만 흥미로운 일반적인 아이디어입니다.
Jon Skeet

4
특히 값 유형과 함께 일부 내부 도메인 별 언어 사용이 있습니다. 예를 들면 다음과 같습니다. clock.AlertUser.In (1.Minute)는 clock.AlertUser (TimeSpan.FromMinutes (1))보다 훨씬 잘 읽습니다.
Michael Meadows

17

Google Java Collections 노출에 기반한 이전 답변과 다른 답변 :

public static class Lists
{
    public static List<T> Of<T>(T item)
    {
        return new List<T> { item };
    }
}

그때:

List<string> x = Lists.Of("Hello");

GJC를 확인하는 것이 좋습니다. 많은 흥미로운 것들이 있습니다. (개인적으로 "알파"태그를 무시할 것입니다- "알파"인 오픈 소스 버전 일 뿐이며 매우 안정적이고 많이 사용되는 내부 API를 기반으로합니다. .)



7

메소드 체인과 함께 확장 메소드를 사용하십시오.

public static List<T> WithItems(this List<T> list, params T[] items)
{
    list.AddRange(items);
    return list;
}

이렇게하면이 작업을 수행 할 수 있습니다.

List<string> strings = new List<string>().WithItems("Yes");

또는

List<string> strings = new List<string>().WithItems("Yes", "No", "Maybe So");

최신 정보

이제리스트 이니셜 라이저를 사용할 수 있습니다 :

var strings = new List<string> { "This", "That", "The Other" };

http://msdn.microsoft.com/en-us/library/bb384062(v=vs.90).aspx 참조


어쩌면 이것은 2009 년 이후의 최신 버전의 C # 때문일 수 있지만 new List<string> {"Yes"}더 나은 것으로 나타났습니다 ...?
ErikE

@ErikE Microsoft 설명서 ( msdn.microsoft.com/en-us/library/bb384062(v=vs.90).aspx ) 에 따르면 이것은 Visual Studio 2008에서 지원되었습니다. 당시에는 너무 복잡했습니다. 업데이트 중입니다.
Michael Meadows

7

또 다른 방법은 "C # /. Net Little wonders"에 있습니다 (불행히도 사이트는 더 이상 존재하지 않습니다).

Enumerable.Repeat("value",1).ToList()

혼란 스럽지만 영리합니다.
PRMan

4

java로 열거 가능한 단일 항목의 경우 Collections.singleton ( "string");

C #에서는 새로운 List보다 효율적입니다.

public class SingleEnumerator<T> : IEnumerable<T>
{
    private readonly T m_Value;

    public SingleEnumerator(T value)
    {
        m_Value = value;
    }

    public IEnumerator<T> GetEnumerator()
    {
        yield return m_Value;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        yield return m_Value;
    }
}

그러나 프레임 워크를 사용하는 간단한 방법이 있습니까?


그것은 실제로 제 의견으로는 가장 좋은 대답입니다. 할당 크기를 줄이기 위해 단일 항목 목록을 갖는 것이 매우 일반적인 패턴입니다. 이미 지름길을 찾고 있다면 편의와 장점을 결합 할 수도 있습니다.
Alex


2

나는이 작은 기능을 가지고있다 :

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

그것은 구체적인 리턴 타입을 규정하지 않기 때문에 이것은 매우 일반적이기 때문에 모든 곳에서 사용합니다. 코드는 다음과 같습니다

CoreUtil.ToEnumerable("title").ToList();

그러나 물론 그것은 또한

CoreUtil.ToEnumerable("title1", "title2", "title3").ToArray();

하나의 항목을 LINQ 문의 출력에 추가하거나 추가해야 할 때 종종 사용합니다. 예를 들어 선택 목록에 빈 항목을 추가하려면

CoreUtil.ToEnumerable("").Concat(context.TrialTypes.Select(t => t.Name))

몇 가지 ToList()Add진술을 저장합니다 .

(늦은 대답,하지만 나는이 oldie를 우연히 발견하고 이것이 도움이 될 수 있다고 생각했습니다)



2

다른 답변에서 영감을 얻었으며 (필요할 때마다 선택할 수 있습니다!) F # ( singleton데이터 구조 당 표준 기능 이있는 *) 과 일치하는 이름 / 스타일을 사용합니다 .

namespace System.Collections.Generic
{
    public static class List
    {
        public static List<T> Singleton<T>(T value) => new List<T>(1) { value };
    }
}

* ResizeArray물론 그 자체를 제외 하고는 이 질문 :)


실제로 나는 실제로 , [2] Create등 내가 정의한 다른 도우미와 정렬되도록 이름을 지정합니다 .Tuple.CreateLazy.CreateLazyTask.Create

namespace System.Collections.Generic
{
    public static class List
    {
        public static List<T> Create<T>(T value) => new List<T>(1) { value };
    }
}

[2]

namespace System
{
    public static class Lazy
    {
        public static Lazy<T> Create<T>(Func<T> factory) => new Lazy<T>(factory);
    }
}

감사! 내 솔루션도. 몇 가지 사항 : (1) 목록 구현은 공개되지 않으므로 선언 어셈블리 외부에서 사용할 수 없으며 (2) 시스템 네임 스페이스에 넣는 목적은 무엇입니까?
Codure

@StephenRobinson Lazy확장 을 넣은 이유 System는 그 Lazy자체가 System[따라서 Createcompleiton 목록에 나타나지 않기 때문 using입니다.] 사람들에게 opendiff 네임 스페이스 를 강요함으로써 얻을 수있는 것은 없습니까? 다른 것을 사적으로 만드는 것은 의도적이지 않았습니다. 고정
Ruben Bartelink

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