문제

객체 초기화기는 JSON과 매우 유사하며 이제 .NET에는 익명 유형이 있습니다. JSON과 같은 문자열을 가져 와서 JSON 문자열을 나타내는 익명의 객체를 만들 수 있다는 것은 멋질 것입니다.

객체 이니셜 라이저를 사용하여 익명 유형을 만듭니다.

var person = new {
    FirstName = "Chris",
    LastName = "Johnson"
};

객체 이니셜 라이저 코드 (바람직하게는 JSON과 같은)의 문자열 표현을 전달하여 해당 데이터와 함께 익명 유형의 인스턴스를 만들 수 있다면 굉장합니다.

C#이 동적이지 않고 컴파일러가 실제로 객체 이니셜 라이저를 변환하기 때문에 가능한지 모르겠습니다.d 익명 유형은 실행할 수있는 강력하게 입력 된 코드로 유형입니다. 이것은 설명되어 있습니다 이 기사.

아마도 JSON을 취하고 키/가치 사전을 만들 수있는 기능이 가장 효과적입니다.

.NET의 JSON에 대한 객체를 직렬화/사형화 할 수 있다는 것을 알고 있지만, 내가 찾는 것은 JavaScript의 작동 방식과 마찬가지로 본질적으로 느슨하게 입력되는 객체를 만드는 방법입니다.

.NET 에서이 작업을 수행하기위한 최상의 솔루션을 아는 사람이 있습니까?

업데이트 : 내가 이것을 묻는 이유의 맥락을 너무 명확하게 설명합니다 ... 나는 C#이 언어 수준에서 JSON을 더 잘 지원할 수있는 방법을 생각하고 있었고, 오늘날 개념적으로 할 수있는 방법을 생각하려고했습니다. 원인. 그래서 토론을 시작하기 위해 여기에 게시 할 것이라고 생각했습니다.

도움이 되었습니까?

해결책

.NET에 대한 오리를 사용하는 언어가 있지만 C#을 사용하는 경우에는 불가능합니다. Dot.Notation을 사용하려면 필요한 속성이있는 어딘가에 클래스를 정의하고 JSON 데이터에서 클래스를 인스턴스화하려는 모든 메소드를 사용해야합니다. 수업을 사전 정의합니다 하다 강력한 타이핑, Intellisense를 포함한 IDE 지원 및 철자 실수에 대해 걱정하지 않는 것과 같은 혜택을 누리십시오. 익명 유형을 사용할 수 있습니다.

 T deserialize<T>(string jsonStr, T obj) { /* ... */}

 var jsonString = "{FirstName='Chris', LastName='Johnson, Other='unused'}";
 var person     = deserialize(jsonString, new {FirstName="",LastName=""});
 var x          = person.FirstName; //strongly-typed

다른 팁

당신은 확인해야합니다 json.net 프로젝트:

http://james.newtonking.com/pages/json-net.aspx

당신은 기본적으로 JSON의 물체를 수화시키는 능력에 대해 이야기하고 있습니다. 익명의 유형을 수행하지는 않지만 아마도 당신을 충분히 가까이하게 할 것입니다.

JSON을 구문 분석하고 JavaScript의 실제 객체와 유사하게 액세스 할 수있는 이름/값 사전을 반환하는 비교적 짧은 방법을 작성했습니다.

다음은 아래 방법의 샘플 사용량입니다.

var obj = ParseJsonToDictionary("{FirstName: \"Chris\", \"Address\":{Street:\"My Street\",Number:123}}");

// Access the Address.Number value
object streetNumber = ((Dictionary<string, object>)obj["Address"])["Number"];

그리고 다음은 parsejsontodictionary 방법에 대한 코드입니다.

public static Dictionary<string, object> ParseJsonToDictionary(string json)
{
    var d = new Dictionary<string, object>();

    if (json.StartsWith("{"))
    {
        json = json.Remove(0, 1);
        if (json.EndsWith("}"))
            json = json.Substring(0, json.Length - 1);
    }
    json.Trim();

    // Parse out Object Properties from JSON
    while (json.Length > 0)
    {
        var beginProp = json.Substring(0, json.IndexOf(':'));
        json = json.Substring(beginProp.Length);

        var indexOfComma = json.IndexOf(',');
        string endProp;
        if (indexOfComma > -1)
        {
            endProp = json.Substring(0, indexOfComma);
            json = json.Substring(endProp.Length);
        }
        else
        {
            endProp = json;
            json = string.Empty;
        }

        var curlyIndex = endProp.IndexOf('{');
        if (curlyIndex > -1)
        {
            var curlyCount = 1;
            while (endProp.Substring(curlyIndex + 1).IndexOf("{") > -1)
            {
                curlyCount++;
                curlyIndex = endProp.Substring(curlyIndex + 1).IndexOf("{");
            }
            while (curlyCount > 0)
            {
                endProp += json.Substring(0, json.IndexOf('}') + 1);
                json = json.Remove(0, json.IndexOf('}') + 1);
                curlyCount--;
            }
        }

        json = json.Trim();
        if (json.StartsWith(","))
            json = json.Remove(0, 1);
        json.Trim();


        // Individual Property (Name/Value Pair) Is Isolated
        var s = (beginProp + endProp).Trim();


        // Now parse the name/value pair out and put into Dictionary
        var name = s.Substring(0, s.IndexOf(":")).Trim();
        var value = s.Substring(name.Length + 1).Trim();

        if (name.StartsWith("\"") && name.EndsWith("\""))
        {
            name = name.Substring(1, name.Length - 2);
        }

        double valueNumberCheck;
        if (value.StartsWith("\"") && value.StartsWith("\""))
        {
            // String Value
            d.Add(name, value.Substring(1, value.Length - 2));
        }
        else if (value.StartsWith("{") && value.EndsWith("}"))
        {
            // JSON Value
            d.Add(name, ParseJsonToDictionary(value));
        }
        else if (double.TryParse(value, out valueNumberCheck))
        {
            // Numeric Value
            d.Add(name, valueNumberCheck);
        }
        else
            d.Add(name, value);
    }

    return d;
}

나는이 방법이 약간 거칠다는 것을 알고 있으며 아마도 최적화 될 수 있지만, 첫 번째 초안이며 단지 작동합니다.

또한 정규 표현식을 사용하지 않는 것에 대해 불평하기 전에 모든 사람이 정규 표현을 실제로 이해하는 것은 아니며, 그런 식으로 작성하면 필요한 경우 다른 사람들이 고치기가 더 어려워 질 것입니다. 또한, 나는 현재 정규 표현식을 너무 잘 모르고 문자열 구문 분석이 더 쉬웠습니다.

메소드 **에서 익명 유형을 반환 할 수 없으므로 "재수 화 된"익명 유형의 존재는 재수 화 된 방법으로 제한됩니다. 일종의 무의미합니다.

** 객체로 반환 할 수 있습니다 (특성에 액세스하기 위해 반사가 필요합니다. 객체의 유형은 모양이되어야합니다. 왜 개체를 만들고 처음에 채우지 않겠습니까?

이것에 대한 응용 프로그램은 무엇입니까?

나는 몇 가지 이유로이 길로 가지 않을 것입니다.

  • 첫 번째; 반사를 사용하여 많은 지원 코드가 필요할 수 있습니다.

  • 둘째, 당신이 말했듯이, C#은 강력하게 입력 된 언어이며, 이와 같은 것들은 이유 때문에 언어 사양에서 제외되었습니다.

  • 셋째,이 작업에 대한 오버 헤드는 그만한 가치가 없습니다. 웹 페이지 (특히 Ajax 쿼리)는 실제로 빠르거나 목적을 물리칩니다. 계속해서 C#과 JavaScript 사이에서 객체를 직렬화하는 50%를 소비하면 문제가 있습니다.

내 해결책은 사전을 캡슐화하고 JSON 문자열을 CTOR 인수로 취하는 클래스를 만드는 것입니다. 그런 다음 처리하려는 각 유형의 JSON 쿼리에 대한 해당 클래스를 확장하십시오. 이것은 강력하고 유형이 빠르고 더 빠른 솔루션이지만 여전히 확장 성과 사용 편의성을 유지합니다. 단점은 JSON 요청 유형 당 더 많은 코드가 있다는 것입니다.

:)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top