Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

173
Visualizações
Árbol de expresiones para crear lambda para generar el diccionario ac #

Tengo un flujo de miles de datos que necesito transformar y agregar a una lista. La transformación ocurre a través de la reflexión similar a la siguiente

 _myObservable.Subscribe(d => { PropertyInfo[] props = d.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); var propValDict = props.ToDictionary(prop => prop.Name, prop => prop.GetValue(d, null)); myList.Add(propValDict); }); // Datatype of d is determined during runtime and there are only 8 possibilities of the type

Pero este enfoque está ralentizando el rendimiento y espero que el uso de la reflexión sea la razón. Estoy pensando en mejorar el rendimiento por otros medios.

Las sugerencias parecen apuntar al uso de árboles de expresión, crear lambda compilada (Func<object,Dictionary<string, object>>) y almacenarla en un diccionario de búsqueda de antemano.

 //Foreach possibleType in PossibleTypes, Do below PropertyInfo[] props = possibleType.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); var rootParam = Expression.Parameter(typeof(object), "d"); var param = Expression.Parameter(typeof(PropertyInfo), "prop"); var propertyFirst = Expression.Property(param, "Name"); var param2 = Expression.Parameter(typeof(PropertyInfo), "prop"); var callMethod = Expression.Call(param2, typeof(PropertyInfo).GetMethod(nameof(PropertyInfo.GetValue), new Type[] { typeof(object) }), rootParam); var pro = Expression.Parameter(typeof(Array), "props"); var toDict = Expression.Invoke(pro, propertyFirst, callMethod); var lambda = Expression.Lambda<Func<object, Dictionary<string, object>>>(toDict, rootParam); var compiled = lambda.Compile();

Tengo problemas para invocar ToDictionary de la clase Enumerable Hay algo que me falta con este enfoque o ¿Esto realmente mejorará el rendimiento?

Por favor ayuda...

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Al pensar con expresiones, siempre debe averiguar cómo se vería el código C# equivalente. En este caso, el código C# equivalente no estaría recorriendo una colección de PropertyInfo , sino que probablemente se vería así:

 public static Func<object, Dictionary<string, object>> CreateConvertToPropertyDict<T>() { return input => { var d = (T)input; return new Dictionary<string, object>()) { { "Foo", d.Foo }, { "Bar", d.Bar }, }; }; } myList.Add(propValDict);

Muévase hacia los lados en la tierra de las expresiones, y terminará con algo como:

 public static Func<object, Dictionary<string, object>> CreatePropertyDict(Type type) { // Consider caching these in a static field, since they're constant var dictType = typeof(Dictionary<string, object>); var dictCtor = dictType.GetConstructor(new[] { typeof(int) }); var dictAddMethod = dictType.GetMethod("Add"); var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); var blockExpressions = new List<Expression>(); // 'object input' is our input parameter var inputParameter = Expression.Parameter(typeof(object), "input"); // MyType d; var dVariable = Expression.Variable(type, "d"); // d = (MyType)inputObject; blockExpressions.Add(Expression.Assign(dVariable, Expression.Convert(inputParameter, type))); // Dictionary<string, object> dict; var dictVariable = Expression.Variable(dictType, "dict"); // dict = new Dictionary<string, object>(3) (or however many properties there are) blockExpressions.Add(Expression.Assign(dictVariable, Expression.New(dictCtor, Expression.Constant(properties.Length)))); foreach (var property in properties) { var propertyAccess = Expression.Property(dVariable, property); // dict.Add("Foo", (object)d.Foo) blockExpressions.Add(Expression.Call( dictVariable, dictAddMethod, Expression.Constant(property.Name), Expression.Convert(propertyAccess, typeof(object)))); }; // The final statement in a block is the return value blockExpressions.Add(dictVariable); var block = Expression.Block(new[] { dVariable, dictVariable }, blockExpressions); return Expression.Lambda<Func<object, Dictionary<string, object>>>(block, inputParameter).Compile(); }

Con el caso de prueba simple:

 public static void Main() { var test = new Test() { Foo = "woop", Bar = 3 }; var expr = CreatePropertyDict(typeof(Test)); expr(test).Dump(); }

Véalo en dotnetfiddle .

Hay varios usos más avanzados de Expression aquí, y no voy a entrar en los detalles de cada uno. Mire los documentos y juegue con los tipos de expresiones que genera el compilador de C# para diferentes bits de código de C#.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda