C# - Повторно применить манипуляции с JS Object in. Net Core - PullRequest
0 голосов
/ 06 марта 2020

Я ищу здесь и видел несколько похожих вопросов, но большинство было создано несколько лет спустя go.

Итак, я открою вопрос / обсуждение на простом примере JS о как этот язык облегчает изменение, чтение, запись реквизита в его объектах.

Проверьте следующий код на JS:

const dynamicObject = {
  a: [1, 2],
  b: "String val",
  c: 10,
  d: { sa: 1, sb: null, sc: [1, 2, 3] }
};

// Add new props
const newProp = "e";
dynamicObject[newProp] = "New val";
dynamicObject.f = false;

dynamicObject["d"]["sd"] = null
dynamicObject["d"].se = null

// Modify props
const prop = 'a'
dynamicObject[prop].push(3)
dynamicObject.b += " ABCD"

// Modify children props of another prop
dynamicObject.d.sb = ["New", "Array"]
dynamicObject.d["sa"] += 5

dynamicObject["d"]["sa"] += 5

// Read props
const propValue = dynamicObject[prop]
console.log(propValue)

const propValueString = dynamicObject.b
console.log(propValueString)

Проверьте онлайн результаты здесь

Я пытался повторно применить этот метод, используя C#:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

public class Program
{
    public static void Main()
    {
        dynamic dynamicObject = new {
          a = new int[] {1, 2},
          b = "String val",
          c = 10,
          d = new { sa = 1, sb = "abv", sc = new int[] { 1, 2, 3 } }
        };

        var DO = (IDictionary<string, object>)dynamicObject;

        // Add new props
        const string newProp = "e";
        dynamicObject[newProp] = "New val";
        dynamicObject.f = false;

        dynamicObject["d"]["sd"] = null;
        dynamicObject["d"].se = null;

        // Modify props
        const string prop = "a";
        dynamicObject[prop].push(3);
        dynamicObject.b += " ABCD";

        // Modify children props of another prop
        dynamicObject.d.sb = new string[] { "New", "Array" };
        dynamicObject.d["sa"] += 5;

        dynamicObject["d"]["sa"] += 5;

        // Read props
        object propValue = dynamicObject[prop];
        object propValueString = dynamicObject.b;

        string result = JsonConvert.SerializeObject(dynamicObject);

        Console.WriteLine(result);
    }
}

. Net Пример Fiddle здесь

Но, очевидно, он не работает должным образом.

Я знаю, что мы можем использовать ExpandoObject или dynamic или для доступа к реквизиту через строковый параметр, преобразующий объект в IDictionary<string, object>. Я не хочу фокусировать внимание на разнице в том, что C# является языком со строгой типизацией.

Но, C# все еще не реализует какую-либо структуру / объект / библиотеку для простого управления манипуляциями с объектами, такими как JS?

1 Ответ

0 голосов
/ 07 марта 2020

ВАЖНО:

Я сделал еще одну версию с некоторыми улучшениями: Версия 2


Я создал свой собственный класс, чтобы сделать больше Dynami c взаимодействие с Object / Dynamic / ExpandoObjects с использованием C# Net Core

ПРОВЕРЬТЕ КОД ЗДЕСЬ

Вот полный код:

namespace FW {
    public class Expando
    {
        public Expando(dynamic value)
        {
            expando = ToExpando(value);
        }

        public ExpandoObject root { get => expando; }

        private ExpandoObject expando { get; set; }

        private ExpandoObject ToExpando(dynamic dynamicObject)
        {
            if ((dynamicObject as object).GetType().Name == "ExpandoObject") return dynamicObject;

            if (!(dynamicObject as object).GetType().IsGenericType) throw new Exception("No generic type");

            ExpandoObject expando = new ExpandoObject();

            ((object)dynamicObject)
            .GetType()
                .GetProperties()
                .ToList()
                .ForEach(p => expando.fwAddProperty(p.Name, p.GetValue(dynamicObject) as object));

            return expando;
        }

        public dynamic this[string prop]
        {
            get => expando.fwReadProperty(prop);
            set => expando.fwAddProperty(prop, value as object);
        }

        public dynamic this[params string[] props]
        {
            get
            {
                ExpandoObject returnValue = expando;

                foreach (string prop in props)
                {
                    var temp = returnValue.fwReadProperty(prop);

                    try { returnValue = ToExpando(temp); }
                    catch { return temp as object; }
                }

                return returnValue;
            }
            set
            {
                List<ExpandoObject> list = new List<ExpandoObject>();
                list.Add(expando);

                foreach (var prop in props)
                {
                    var newProp = list.Last().fwReadProperty(prop);

                    if (newProp != null)
                    {
                        try { list.Add(ToExpando(newProp)); }
                        catch { }
                    }
                    else if (prop != props.Last())
                    {
                        ExpandoObject expandoTemp = new ExpandoObject();
                        list.Add(expandoTemp);
                    }
                }

                List<string> nodeProps = props.ToList();
                list.Last().fwAddProperty(nodeProps.Last(), value as object);

                nodeProps.RemoveAt(nodeProps.Count - 1);

                ExpandoObject ExpandoTemp = list.Last();
                list.RemoveAt(list.Count - 1);

                while (list.Count != 0)
                {
                    var node = list.Last();
                    list.RemoveAt(list.Count - 1);

                    node.fwAddProperty(nodeProps.Last(), ExpandoTemp as object);
                    nodeProps.RemoveAt(nodeProps.Count - 1);

                    ExpandoTemp = node;
                }

                expando = ExpandoTemp;
            }
        }
    }

    public static class extExpandoObject
    {
        public static void fwAddProperty(this ExpandoObject expando, string propertyName, object propertyValue)
        {
            // ExpandoObject supports IDictionary so we can extend it like this
            var expandoDict = expando as IDictionary<string, object>;

            if (expandoDict.ContainsKey(propertyName))
                expandoDict[propertyName] = propertyValue;
            else
                expandoDict.Add(propertyName, propertyValue);
        }

        public static object fwReadProperty(this ExpandoObject expando, string propertyName)
        {
            // ExpandoObject supports IDictionary so we can extend it like this
            var expandoDict = expando as IDictionary<string, object>;

            if (expandoDict.ContainsKey(propertyName))
                return expandoDict[propertyName];
            else
                return null;
        }
    }
}

Вот пример реализации:

public class Program
{
    public static void Main()
    {
        FW.Expando dynamicObject = 
            new FW.Expando(new
                           {
                               a = new int[] { 1, 2 },
                               b = "String val",
                               c = 10,
                               d = new { sa = 1, sb = "abv", sc = new int[] { 1, 2, 3 } }
                           });

        // Add new props
        const string newProp = "e";
        dynamicObject[newProp] = "New val";
        dynamicObject["f"] = false;

        dynamicObject["d", "sd"] = "SDSDSD";
        var a = dynamicObject["d", "sd"];

        dynamicObject["d", "se"] = null;

        // Modify props
        const string prop = "a";
        dynamicObject[prop] = (dynamicObject[prop] as int[]).Append(3).ToArray();
        dynamicObject["b"] += " ABCD";

        // Modify children props of another prop
        dynamicObject["d", "sb"] = new string[] { "New", "Array" };

        dynamicObject["d", "sa"] += 5;

        dynamicObject["d", "sa"] = new { dz = "ABA", zz = "WCC", ZXXX = new { Y1 = "1", Y2 = "2" } };

        dynamicObject["parent", "node"] = "New field";

        dynamicObject["parent-node", "node-lvl1", "node-lvl1.1"] = "P > 1 > 1.1";
        dynamicObject["parent-node", "node-lvl1", "node-lvl1.2"] = "P > 1 > 1.2";
        dynamicObject["parent-node", "node-lvl2", "node-lvl2.1"] = "P > 2 > 2.1";
        dynamicObject["parent-node", "m-node", "sub1", "sub2", "sub3"] = "3 Sublevels";

        // Read props
        object propValue = dynamicObject[prop];
        object propValueString = dynamicObject["b"];

        string result = Newtonsoft.Json.JsonConvert.SerializeObject(dynamicObject.root);

        // CHECK MORE EASILY THE RESULT: https://jsonformatter.curiousconcept.com/
        Console.WriteLine("\r\n" + result + "\r\n");
    }
}

Это результат в JSON:

{
   "a":[
      1,
      2,
      3
   ],
   "b":"String val ABCD",
   "c":10,
   "d":{
      "sa":{
         "dz":"ABA",
         "zz":"WCC",
         "ZXXX":{
            "Y1":"1",
            "Y2":"2"
         }
      },
      "sb":[
         "New",
         "Array"
      ],
      "sc":[
         1,
         2,
         3
      ],
      "sd":"SDSDSD",
      "se":null
   },
   "e":"New val",
   "f":false,
   "parent":{
      "node":"New field"
   },
   "parent-node":{
      "node-lvl1":{
         "node-lvl1.1":"P > 1 > 1.1",
         "node-lvl1.2":"P > 1 > 1.2"
      },
      "node-lvl2":{
         "node-lvl2.1":"P > 2 > 2.1"
      },
      "m-node":{
         "sub1":{
            "sub2":{
               "sub3":"3 Sublevels"
            }
         }
      }
   }
}

Что вы думаете? Любые дополнительные отзывы или комментарии?

Просто отказ от ответственности, подуровни в JSON используются в одном массиве.

  • Запись: dynamicObject["parent", "node"] = "New field";
  • Чтение: dynamicObject["parent", "node"];

И я не могу сделать реализацию без использования строки. Пример: dynamicObject["myProp"] = "propValue" вместо dynamicObject.myProp = "propValue"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...