C #에서 사전에 대한 리터럴 표기법?


182

현재 JavaScript와 C #으로 프로그래밍 된 서버 사이에 WebSocket이 있습니다. JavaScript에서는 연관 배열을 사용하여 데이터를 쉽게 전달할 수 있습니다.

var data = {'test': 'val',
            'test2': 'val2'};

서버 측 에서이 데이터 객체를 나타 내기 위해을 사용 Dictionary<string, string>하지만 JavaScript보다 '타이핑 비용이 많이 듭니다'.

Dictionary<string, string> data = new Dictionary<string,string>();
data.Add("test", "val");
data.Add("test2", "val2");

DictionaryC #에서 연관 배열 / s에 대한 일종의 리터럴 표기법이 있습니까?


C # 9에는 Dictionary Literals에 대한 제안이 포함되어 있습니다. 아래에 이에 대한 답변을 게시 합니다 . 우리의 꿈이 이루어집니다!
codidact.com로 이동 aloisdg

답변:


291

당신은 사용 초기화 수집을 구문,하지만 당신은 여전히해야 할 new Dictionary<string, string>바로 가기 구문의 무리로 변환 될 때 첫 번째 개체를 Add()(코드와 같은) 전화 :

var data = new Dictionary<string, string>
{
    { "test", "val" }, 
    { "test2", "val2" }
};

C # 6에서는 이제 Dictionary뿐만 아니라 인덱서 를 지원하는 다른 유형과 함께보다 직관적 인 구문을 사용할 수 있습니다 . 위의 진술은 다음과 같이 다시 작성할 수 있습니다.

var data = new Dictionary<string, string>
{
    ["test"] = "val",
    ["test2"] = "val2"
};

컬렉션 이니셜 라이저와 달리 이것은 적절한 Add()메소드가 아닌 후드 아래에서 인덱서 세터를 호출합니다 .


2
감사. Dictionary<string, string>그래도 하나를 제거 할 수 있습니까? 다소 중복 된 것처럼 보이지만 잘못되었을 수 있습니다. 편집 : 이것은 실제로 더 바람직한 방법으로 보입니다. 감사합니다.
pimvdb 2019

3
@pimvdb : 그렇습니다.으로 선언 var하면 컴파일러가에서 형식을 유추합니다 new. 내 답변을 편집했습니다.
BoltClock

7
문자 그대로의 표기법이 아니며 엄밀히 말하면 초기화에 대한 바로 가기 일뿐입니다. 문자열과 일부 기본 유형 만 문자 그대로 표시됩니다.
Thomas Levesque

"문자열"중 하나를 제거하려는 경우 (중복이 아님) 하나는 키 유형이고 다른 하나는 값 유형입니다. 사전에 고유 한 문자가 없으므로이 답변에 사용 된 표기법은 두 개의 문자열을 사용하고 IEnumerable을 구현하는 Add 메서드가있는 모든 클래스에 일반적입니다.
Markus Johnsson

1
@Markus Johnsson : 그는 말 그대로 Dictionary<string, string>. 내 코드는 원래 유형을 선언했으며 방금 var주석 후에 변경했습니다 .
BoltClock

13

사전 이니셜 라이저 답변은 완전히 정확하지만, 지적 할 다른 접근 방식이 있지만 권장하지는 않습니다. 간결한 API 사용을 제공하는 것이 목표라면 익명 객체를 사용할 수 있습니다.

var data = new { test1 = "val", test2 = "val2"};

그런 다음 "data"변수는 "말할 수없는"익명 유형이므로이로만 전달할 수 System.Object있습니다. 그런 다음 익명 개체를 사전으로 변환 할 수있는 코드를 작성할 수 있습니다. 이러한 코드는 리플렉션에 의존하며 잠재적으로 느릴 수 있습니다. 그러나을 사용 System.Reflection.Emit하거나 System.Linq.Expressions후속 호출을 훨씬 빠르게하는 델리게이트를 컴파일하고 캐시 할 수 있습니다 .

Asp.net MVC API는 내가 본 여러 곳에서이 기술을 사용합니다. 많은 Html 도우미에는 개체 또는 사전을 허용하는 오버로드가 있습니다. API 디자인의 목표는 당신이 추구하는 것과 동일하다고 가정합니다. 메소드 호출에서 간결한 구문.


1
키 세트가 정적 일 때만 도움이됩니다. 동일한 목적으로 튜플을 사용할 수도 있습니다.
sehe

8

를 사용 DynamicObject하면 더 간단한 사전 이니셜 라이저를 만드는 것이 어렵지 않습니다.

다음 방법을 호출한다고 상상해보십시오.

void PrintDict(IDictionary<string, object> dict) {
    foreach(var kv in dict) {
        Console.WriteLine ("  -> " + kv.Key + " = " + kv.Value);
    }
}

다음과 같은 리터럴 구문 사용

var dict = Dict (Hello: "World", IAm: "a dictionary");
PrintDict (dict);

이 같은 동적 개체를 만들어서 달성 할 수 있습니다

dynamic Dict {
    get {
        return new DynamicDictFactory ();
    }
}

private class DynamicDictFactory : DynamicObject
{
    public override bool TryInvoke (InvokeBinder binder, object[] args, out object result)
    {
        var res = new Dictionary<string, object> ();
        var names = binder.CallInfo.ArgumentNames;

        for (var i = 0; i < args.Length; i++) {
            var argName = names [i];
            if(string.IsNullOrEmpty(argName)) throw new ArgumentException();
            res [argName] = args [i];
        }
        result = res;
        return true;
    }
}

6

사전 리터럴 사용 (C # 9 제안)

C # 9 Dictionary<TKey,TValue>는 사전 형식 이름이나 형식 매개 변수를 지정하지 않고도 초기화 된 개체 를 만드는 간단한 구문을 도입했습니다 . 사전의 유형 매개 변수는 배열 유형 유추에 사용 된 기존 규칙을 사용하여 추론됩니다.

// C# 1..8    
var x = new Dictionary <string,int> () { { "foo", 4 }, { "bar", 5 }};   
// C# 9    
var x = ["foo":4, "bar": 5];  

이 synthax는 C #에서 사전 작업을 단순화하고 중복 코드를 제거합니다.

GitHub 에서이 문제를 따를 수 있습니다 ( C # 9이정표입니다 ).

수정 :이 제안은 현재 거부되었습니다 .

[...] 데이터 초기화와 관련하여, 특히 불변의 사전과 같은 흥미로운 사용 사례가 많이 있다고 생각합니다. 우리는 번거로운 사전을 초기화하기위한 기존 구문을 찾지 못하며, 언어 기능에서 많은 이점을 얻을 수있는 코드에서이 패턴을 빈번한 패턴으로 보지도 않습니다. 우리는 기록과 시들기를 한 후에 데이터 초기화의 일반적인 영역을 다시 살펴보아야합니다. [...]


1
좋은 생각, 그것이 만들어지기를 바랍니다. 더
똑똑
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.