13,347
社区成员
发帖
与我相关
我的任务
分享
public static T ToClientEntity<T>(this ServerEntityBase sData) where T: ClientDataEntity,new()
{
T tempResult = new T();
PropertyInfo serProperty;
object proValue;
foreach (PropertyInfo item in tempResult.GetType().GetProperties())
{
EntityConvertAttribute convertAtt = Attribute.GetCustomAttribute(item, typeof(EntityConvertAttribute)) as EntityConvertAttribute;
if (convertAtt == null)
{
continue;
}
serProperty = sData.GetType().GetProperty(convertAtt.ServerEntity_Name);
if (serProperty == null)
{
continue;
}
proValue = serProperty.GetValue(sData);
if(proValue == null)
{
continue;
}
if (!convertAtt.IsTypeConvert || item.PropertyType.Name == proValue.GetType().Name)
{
item.SetValue(tempResult, Convert.ChangeType(proValue,item.PropertyType));
SpecialConvert(tempResult, proValue, item);
continue;
}
MethodInfo convertFun = tempResult.GetType().GetMethod(convertAtt.ConvertToClient, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
object setValue = convertFun?.Invoke(tempResult, new object[] { proValue });
if (setValue == null)
{
continue;
}
item.SetValue(tempResult, setValue);
SpecialConvert(tempResult, setValue, item);
}
return tempResult;
}
public delegate void SetValueDelegate(object target, object arg);
public static class DynamicMethodFactory
{
public static SetValueDelegate CreatePropertySetter(PropertyInfo property)
{
if (property == null)
throw new ArgumentNullException("property");
if (!property.CanWrite)
return null;
MethodInfo setMethod = property.GetSetMethod(true);
DynamicMethod dm = new DynamicMethod("PropertySetter", null,
new Type[] { typeof(object), typeof(object) }, property.DeclaringType, true);
ILGenerator il = dm.GetILGenerator();
if (!setMethod.IsStatic)
{
il.Emit(OpCodes.Ldarg_0);
}
il.Emit(OpCodes.Ldarg_1);
EmitCastToReference(il, property.PropertyType);
if (!setMethod.IsStatic && !property.DeclaringType.IsValueType)
{
il.EmitCall(OpCodes.Callvirt, setMethod, null);
}
else
il.EmitCall(OpCodes.Call, setMethod, null);
il.Emit(OpCodes.Ret);
return (SetValueDelegate)dm.CreateDelegate(typeof(SetValueDelegate));
}
private static void EmitCastToReference(ILGenerator il, Type type)
{
if (type.IsValueType)
il.Emit(OpCodes.Unbox_Any, type);
else
il.Emit(OpCodes.Castclass, type);
}
}
class Digit
{
public Digit(double d) { val = d; }
public double val;
// ...other members
// User-defined conversion from Digit to double
public static implicit operator double(Digit d)
{
return d.val;
}
// User-defined conversion from double to Digit
public static implicit operator Digit(double d)
{
return new Digit(d);
}
}
class Program
{
static void Main(string[] args)
{
Digit dig = new Digit(7);
//This call invokes the implicit "double" operator
double num = dig;
//This call invokes the implicit "Digit" operator
Digit dig2 = 12;
Console.WriteLine("num = {0} dig2 = {1}", num, dig2.val);
Console.ReadLine();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace T392496087
{
class A
{
public string Str { get; set; }
public int IntVal { get; set; }
}
class B
{
public string str { get; set; }
public int intval { get; set; }
public override string ToString()
{
return string.Format("B str = {0}, intval = {1};", str, intval);
}
}
class Program
{
static List<A> GenAList(int count)
{
List<A> list = new List<A>();
Random rnd = new Random();
for (int i = 1; i <= count; i++)
list.Add(new A { IntVal = rnd.Next(0, 100), Str = "A:" + i.ToString() });
return list;
}
static List<B> HardCoded(List<A> list)
{
return list.Select(x => new B() { intval = x.IntVal, str = x.Str }).ToList();
}
static List<B> ByReflection(List<A> list)
{
var props = typeof(A).GetProperties().Select(x => new { a = x, b = typeof(B).GetProperty(x.Name.ToLower()) });
return list.Select(x => {
B b = new B();
foreach (var item in props)
item.b.SetValue(b, item.a.GetValue(x, null));
return b;
}).ToList();
}
static List<B> ByExpTree(List<A> list)
{
var props = typeof(A).GetProperties().Select(x => new { a = x, b = typeof(B).GetProperty(x.Name.ToLower()) });
var param = Expression.Parameter(typeof(A), "x");
List<Expression> exps = new List<Expression>();
var cre = Expression.New(typeof(B));
var newb = Expression.Variable(typeof(B));
var assb = Expression.Assign(newb, cre);
exps.Add(assb);
foreach (var item in props)
{
var getexp = Expression.MakeMemberAccess(param, item.a);
var setexp = Expression.MakeMemberAccess(newb, item.b);
var ass = Expression.Assign(setexp, getexp);
exps.Add(ass);
}
exps.Add(newb);
var body = Expression.Block(new ParameterExpression [] { newb }, exps);
var sel = Expression.Lambda<Func<A, B>>(body, param);
return list.Select(sel.Compile()).ToList();
}
static void TestIt(string title, Func<List<A>, List<B>> foo, int count, int maxoutput = 5)
{
var listA = GenAList(count);
DateTime dt = DateTime.Now;
var listB = foo(listA);
DateTime dt2 = DateTime.Now;
Console.WriteLine(title);
Console.WriteLine("time spent: " + new TimeSpan(dt2.Ticks - dt.Ticks).TotalSeconds + " sec.");
string omit = "";
if (count <= maxoutput)
maxoutput = count;
else
omit = "...\n";
for (int i = 0; i < maxoutput; i++)
Console.WriteLine(listB[i]);
Console.Write(omit);
}
static void Main(string[] args)
{
int n = 200000;
TestIt("HardCoded", HardCoded, n);
TestIt("ByReflection", ByReflection, n);
TestIt("ByExpTree", ByExpTree, n);
}
}
}
public static User Converter2User(IDataRecord rd)
{
return new User{
name= (string)rd["name"],
address=(string)rd["addr"],
level = 获取组织架构层级((string)rd["department"])
};
这样一个方法,甚至是var func = new Func<IDataRecord,User>(rd=>
new User{
name= (string)rd["name"],
address=(string)rd["addr"],
level = 获取组织架构层级((string)rd["department"])
});
就可以用到类似var result = (from IDataRecord rd in dbcommand.ExecuteReader()
select Convert2User(rd)).ToList();
或者var result = (from IDataRecord rd in dbcommand.ExecuteSca()
select func(rd)).ToList();
这样的代码中。
所以说到性能,不管是静态写一个转换过程,还是动态产生一个委托(#5楼使用 Linq 表达式树动态产生委托函数),总之是类型越强则性能越靠谱。