In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "how to achieve object replication by using expression tree in C #". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "how to copy objects using expression tree in C #".
Requirement background: object replication performance optimization; at the same time, null value replication of reference types should be skipped, and value types support replication from value types to nullable types
Using Common;using System;class Program {static void Main (string [] args) {TestClassA classA = new TestClassA () {PropA = new TestClass () {Name = "cs1"}, PropB = "C1", PropC = 1}; TestClassA classB = new TestClassA () {PropA = new TestClass () {Name = "cs2"}, PropB = "c2", PropC = 2}; FastCopy.Copy (classA, classB, false) Console.WriteLine (classB.PropA?.Name + ":" + classB.PropB + ":" + classB.PropC); TestClassA classC = new TestClassA () {PropA = new TestClass () {Name = "cs1"}}; TestClassA classD = new TestClassA () {PropA = new TestClass () {Name = "cs2"}, PropB = "c2", PropC = 2}; FastCopy.Copy (classC, classD, false) Console.WriteLine (classD.PropA?.Name + ":" + classD.PropB + ":" + classD.PropC);} public class TestClassA {public TestClass PropA {get; set;} public string PropB {get; set;} public int? PropC {get; set;}} public class TestClass {public string Name {get; set;}}
Output:
Time spent on millions of calls: 270-300ms
Using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Linq;using System.Linq.Expressions;using System.Reflection;using static System.Linq.Expressions.Expression;namespace Common {public static class FastCopy {static ConcurrentDictionary copiers = new ConcurrentDictionary () / copy two objects with the same name attribute value / / Source object / destination object / when the source object attribute value is null Whether to copy the value to the target object public static void Copy (S source, T target, bool copyNull = true) {string name = string.Format ("{0} _ {1} _ {2}", typeof (S), typeof (T), copyNull) Object targetCopier; if (! copiers.TryGetValue (name, out targetCopier)) {Action copier = CreateCopier (copyNull); copiers.TryAdd (name, copier); targetCopier = copier;} Action action = (Action) targetCopier; action (source, target) } / generate attributes for the two specified types of compilation copy delegate / when the source object property value is null Whether to copy the value to the target object / private static Action CreateCopier (bool copyNull) {ParameterExpression source = Parameter (typeof (S)) ParameterExpression target = Parameter (typeof (T)); var sourceProps = typeof (S) .GetProperties (BindingFlags.Instance | BindingFlags.Public) .Where (p = > p.CanRead). ToList (); var targetProps = typeof (T) .GetProperties (BindingFlags.Instance | BindingFlags.Public) .Where (p = > p.CanWrite). ToList () / / find the attribute var copyProps = targetProps.Where that can be assigned (tProp = > sourceProps.Where (sProp = > sProp.Name = = tProp.Name//) with the same name and & & (sProp.PropertyType = = tProp.PropertyType// attribute type or | | sProp.PropertyType.IsAssignableFrom (tProp.PropertyType) / / subclass where the source attribute type is the target attribute type Eg:object target = string source; or | | (tProp.PropertyType.IsValueType & & sProp.PropertyType.IsValueType & & / / attribute is the value type and the base type is the same, but the target attribute is the nullable type eg:int? Num = int num; ((tProp.PropertyType.GenericTypeArguments.Length > 0? TProp.PropertyType.GenericTypeArguments [0]: tProp.PropertyType) = = sProp.PropertyType)). Count () > 0); List expressionList = new List (); foreach (var prop in copyProps) {if (prop.PropertyType.IsValueType) / / attribute is the value type {PropertyInfo sProp = typeof (S) .GetProperty (prop.Name) PropertyInfo tProp = typeof (T) .GetProperty (prop.Name); if (sProp.PropertyType = = tProp.PropertyType) / / attribute type consistent eg:int num = int num; or int? Num = int? Num; {var assign = Assign (Property (target, prop.Name), Property (source, prop.Name)); expressionList.Add (assign);} else if (sProp.PropertyType.GenericTypeArguments.Length 0) / / attribute type is inconsistent and the target attribute type is nullable eg:int? Num = int num; {var convert = Convert (Expression.Property (source, prop.Name), tProp.PropertyType); var cvAssign = Assign (Expression.Property (target, prop.Name), convert); expressionList.Add (cvAssign) }} else// attribute is the reference type {var assign = Assign (Property (target, prop.Name), Property (source, prop.Name)); / / build the attribute assignment statement target. {PropertyName} = source. {PropertyName} Var sourcePropIsNull = Equal (Constant (null, prop.PropertyType), Property (source, prop.Name)); / / determine whether the source attribute value is Null Compile and generate source. {PropertyName} = = null var setNull = IsTrue (Constant (copyNull)); / / determine whether to copy null values to generate copyNull = = True var setNullTest = IfThen (setNull, assign); var condition = IfThenElse (sourcePropIsNull, setNullTest, assign) / * compile and generate * if (source. {PropertyName} = = null) * {* if (setNull) * {* target. {PropertyName} = source. {PropertyName} * else * {* target. {PropertyName} = source. {PropertyName}; *} * / expressionList.Add (condition) } var block = Block (expressionList.ToArray ()); Expression lambda = Lambda (block, source, target); return lambda.Compile ();}
If you copy it completely, get rid of logical judgment, and through generic classes, you can no longer use dictionaries, and performance can be improved.
Using System;using System.Linq;using System.Linq.Expressions;using System.Reflection;namespace Common {public static class FastCopy {static Action action = CreateCopier () / copy two objects with the same name attribute value / / Source object / destination object / when the source object attribute value is null Whether to copy the value to the target object public static void Copy (S source, T target, bool copyNull = true) {action (source, target) } / generate attributes for the two specified types of compilation copy delegate / when the source object property value is null Whether to copy the value to the target object / private static Action CreateCopier () {ParameterExpression source = Expression.Parameter (typeof (S)) ParameterExpression target = Expression.Parameter (typeof (T)); var sourceProps = typeof (S) .GetProperties (BindingFlags.Instance | BindingFlags.Public) .Where (p = > p.CanRead). ToList (); var targetProps = typeof (T) .GetProperties (BindingFlags.Instance | BindingFlags.Public) .Where (p = > p.CanWrite). ToList () / / find the attribute var copyProps = targetProps.Where that can be assigned (tProp = > sourceProps.Where (sProp = > sProp.Name = = tProp.Name// name is the same and & & (sProp.PropertyType = = tProp.PropertyType// attribute type is the same) .Count () > 0) Var block = Expression.Block (from p in copyProps select Expression.Assign (Expression.Property (target, p.Name), Expression.Property (source, p.Name)); Expression lambda = Expression.Lambda (block, source, target); return lambda.Compile ();}
Time consuming for millions of times: 100ms or so
At this point, I believe you have a deeper understanding of "how C # uses the expression tree to achieve object replication". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.