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.