//TODO 需要去掉动态泛型,改为写死所有支持的类型 public static ISetValue CreatePropertySetterWrapper(PropertyInfo propertyInfo) { if (propertyInfo == null) { throw new ArgumentNullException("propertyInfo is null"); } if (propertyInfo.CanWrite == false) { throw new NotSupportedException("属性不支持写操作。"); } ISetValue setter = null; if (_propertySettersCache.TryGetValue(propertyInfo, out setter)) { return(setter); } MethodInfo mi = propertyInfo.GetSetMethod(true); if (mi.GetParameters().Length > 1) { throw new NotSupportedException("不支持构造索引器属性的委托。"); } Type instanceType = typeof(SetterWrapper <,>).MakeGenericType(propertyInfo.DeclaringType, propertyInfo.PropertyType); setter = (ISetValue)Activator.CreateInstance(instanceType, propertyInfo); _propertySettersCache[propertyInfo] = setter; return(setter); }
IEnumerator IE_OnceMorphing(ISetValue _fun, int _index, ValueData _org, ValueData _target, float _useTime, EasingEquation _easingType) { var _end = false; var _timer = 0f; var _v = 0f; var _cur = new ValueData(); _cur.data = new float[4]; var _type = (MorphingValueType)_index; while (!_end) { if (_v >= 1) { _end = true; } else { _timer += Time.deltaTime; } _v = Mathf.Clamp01(_timer / _useTime); DataValueMorphing(ref _cur, _org, _target, _easingType, _v); _fun.SetValue(_type, _cur); yield return(null); } }
public EntryMap( [Feature(Feature.Dict, Feature.Rank, Feature.RankMulti)] KeyType key, [Payload(Payload.Value)] ValueType value) { this.key = key; this.value = value; this.enumerator = null; this.version = 0; }
public static ISetValue GetPropertySetterWrapper(MemberInfo memberInfo) { ISetValue property = (ISetValue)sSetterDict[memberInfo]; if (property == null) { property = CreatePropertySetterWrapper(memberInfo); sSetterDict[memberInfo] = property; } return(property); }
static void Main(string[] args) { Packaging <string> stringPackage = new Packaging <string>(); ISetValue <string> setStringValue = stringPackage; setStringValue.SetData("Sample string"); // the line below causes a compile-time error IGetValue <object> getObjectValue = stringPackage; Console.WriteLine("{0}", getObjectValue.GetData()); }
internal static ISetValue GetPropertySetterWrapper(PropertyInfo propertyInfo) { ISetValue property = (ISetValue)s_setterDict[propertyInfo]; if (property == null) { property = CreatePropertySetterWrapper(propertyInfo); s_setterDict[propertyInfo] = property; } return(property); }
public EntryRankMap( [Feature(Feature.Dict, Feature.Rank, Feature.RankMulti)] KeyType key, [Payload(Payload.Value)] ValueType value, [Feature(Feature.Rank, Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] int xStart) { this.key = key; this.value = value; this.xStart = xStart; this.enumerator = null; this.version = 0; }
public void Dispose() { if (this.bindingSources != null) { foreach (DataPointBindingObject obj2 in this.bindingSources.ToArray()) { this.RemoveBindingObject(obj2); } } this.bindingSources = null; this.targetElement = null; }
private void loadFunctions() { IntPtr pGetProcessList = GetProcAddress(libInst, "IGetProcessList"); IntPtr pOpenProcess = GetProcAddress(libInst, "IOpenProcess"); IntPtr pResetTable = GetProcAddress(libInst, "IResetTable"); IntPtr pAddScript = GetProcAddress(libInst, "IAddScript"); IntPtr pRemoveRecord = GetProcAddress(libInst, "IRemoveRecord"); IntPtr pActivateRecord = GetProcAddress(libInst, "IActivateRecord"); IntPtr pApplyFreeze = GetProcAddress(libInst, "IApplyFreeze"); IntPtr pAddAddressManually = GetProcAddress(libInst, "IAddAddressManually"); IntPtr pGetValue = GetProcAddress(libInst, "IGetValue"); IntPtr pSetValue = GetProcAddress(libInst, "ISetValue"); IntPtr pProcessAddress = GetProcAddress(libInst, "IProcessAddress"); IntPtr pInitMemoryScanner = GetProcAddress(libInst, "IInitMemoryScanner"); IntPtr pNewScan = GetProcAddress(libInst, "INewScan"); IntPtr pConfigScanner = GetProcAddress(libInst, "IConfigScanner"); IntPtr pFirstScan = GetProcAddress(libInst, "IFirstScan"); IntPtr pNextScan = GetProcAddress(libInst, "INextScan"); IntPtr pCountAddressesFound = GetProcAddress(libInst, "ICountAddressesFound"); IntPtr pGetAddress = GetProcAddress(libInst, "IGetAddress"); IntPtr pInitFoundList = GetProcAddress(libInst, "IInitFoundList"); IntPtr pResetValues = GetProcAddress(libInst, "IResetValues"); IntPtr pGetBinarySize = GetProcAddress(libInst, "IGetBinarySize"); iGetProcessList = (IGetProcessList)Marshal.GetDelegateForFunctionPointer(pGetProcessList, typeof(IGetProcessList)); iOpenProcess = (IOpenProcess)Marshal.GetDelegateForFunctionPointer(pOpenProcess, typeof(IOpenProcess)); iResetTable = (IResetTable)Marshal.GetDelegateForFunctionPointer(pResetTable, typeof(IResetTable)); iAddScript = (IAddScript)Marshal.GetDelegateForFunctionPointer(pAddScript, typeof(IAddScript)); iRemoveRecord = (IRemoveRecord)Marshal.GetDelegateForFunctionPointer(pRemoveRecord, typeof(IRemoveRecord)); iActivateRecord = (IActivateRecord)Marshal.GetDelegateForFunctionPointer(pActivateRecord, typeof(IActivateRecord)); iApplyFreeze = (IApplyFreeze)Marshal.GetDelegateForFunctionPointer(pApplyFreeze, typeof(IApplyFreeze)); iAddAddressManually = (IAddAddressManually)Marshal.GetDelegateForFunctionPointer(pAddAddressManually, typeof(IAddAddressManually)); iGetValue = (IGetValue)Marshal.GetDelegateForFunctionPointer(pGetValue, typeof(IGetValue)); iSetValue = (ISetValue)Marshal.GetDelegateForFunctionPointer(pSetValue, typeof(ISetValue)); iProcessAddress = (IProcessAddress)Marshal.GetDelegateForFunctionPointer(pProcessAddress, typeof(IProcessAddress)); iInitMemoryScanner = (IInitMemoryScanner)Marshal.GetDelegateForFunctionPointer(pInitMemoryScanner, typeof(IInitMemoryScanner)); iNewScan = (INewScan)Marshal.GetDelegateForFunctionPointer(pNewScan, typeof(INewScan)); iConfigScanner = (IConfigScanner)Marshal.GetDelegateForFunctionPointer(pConfigScanner, typeof(IConfigScanner)); iFirstScan = (IFirstScan)Marshal.GetDelegateForFunctionPointer(pFirstScan, typeof(IFirstScan)); iNextScan = (INextScan)Marshal.GetDelegateForFunctionPointer(pNextScan, typeof(INextScan)); iCountAddressesFound = (ICountAddressesFound)Marshal.GetDelegateForFunctionPointer(pCountAddressesFound, typeof(ICountAddressesFound)); iGetAddress = (IGetAddress)Marshal.GetDelegateForFunctionPointer(pGetAddress, typeof(IGetAddress)); iInitFoundList = (IInitFoundList)Marshal.GetDelegateForFunctionPointer(pInitFoundList, typeof(IInitFoundList)); iResetValues = (IResetValues)Marshal.GetDelegateForFunctionPointer(pResetValues, typeof(IResetValues)); iGetBinarySize = (IGetBinarySize)Marshal.GetDelegateForFunctionPointer(pGetBinarySize, typeof(IGetBinarySize)); }
public EntryMap( [Feature(Feature.Dict, Feature.Rank, Feature.RankMulti)] KeyType key, [Payload(Payload.Value)] ValueType value, [Payload(Payload.Value)] ISetValue <ValueType> enumerator, [Payload(Payload.Value)] uint version) { this.key = key; this.value = value; this.enumerator = enumerator; this.version = version; }
public EntryRangeMap( [Payload(Payload.Value)] ValueType value, [Feature(Feature.Rank, Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] int xStart, [Feature(Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] int xLength) { this.value = value; this.xStart = xStart; this.xLength = xLength; this.enumerator = null; this.version = 0; }
/// <summary> /// 一个通用的Morphing函数,可以让对象的指定值在一段时间内达到目标值 /// </summary> /// <param name="_fun">调用的对象必须要有ISetValue接口</param> /// <param name="_org">初始值,是个固定长度的数组,但只需要给用到的赋值</param> /// <param name="_target">目标值</param> /// <param name="_useTime">用时</param> /// <param name="_easingType">缓动类型</param> /// <returns></returns> public IEnumerator IE_Morphing(ISetValue _fun, ValueData[] _org, ValueData[] _target, float _useTime = 0.5f, EasingEquation _easingType = EasingEquation.Linear) { for (var i = 0; i < _org.Length; i++) { if (_org[i].use) { StartCoroutine(IE_OnceMorphing(_fun, i, _org[i], _target[i], _useTime, _easingType)); } } yield return(new WaitForSeconds(_useTime)); }
public EntryRangeMap( [Payload(Payload.Value)] ValueType value, [Payload(Payload.Value)] ISetValue <ValueType> enumerator, [Payload(Payload.Value)] uint version, [Feature(Feature.Rank, Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] int xStart, [Feature(Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] int xLength) { this.value = value; this.xStart = xStart; this.xLength = xLength; this.enumerator = enumerator; this.version = version; }
public EntryMultiRankMapLong( [Feature(Feature.Dict, Feature.Rank, Feature.RankMulti)] KeyType key, [Payload(Payload.Value)] ValueType value, [Feature(Feature.Rank, Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] long xStart, [Feature(Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] long xLength) { this.key = key; this.value = value; this.xStart = xStart; this.xLength = xLength; this.enumerator = null; this.version = 0; }
public EntryRankMapLong( [Feature(Feature.Dict, Feature.Rank, Feature.RankMulti)] KeyType key, [Payload(Payload.Value)] ValueType value, [Payload(Payload.Value)] ISetValue <ValueType> enumerator, [Payload(Payload.Value)] uint version, [Feature(Feature.Rank, Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] long xStart) { this.key = key; this.value = value; this.xStart = xStart; this.enumerator = enumerator; this.version = version; }
public EntryRange2MapLong( [Payload(Payload.Value)] ValueType value, [Feature(Feature.Rank, Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] long xStart, [Feature(Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] long xLength, [Feature(Feature.Range2)][Widen] long yStart, [Feature(Feature.Range2)][Widen] long yLength) { this.value = value; this.xStart = xStart; this.xLength = xLength; this.yStart = yStart; this.yLength = yLength; this.enumerator = null; this.version = 0; }
public Entry( [Feature(Feature.Dict, Feature.Rank, Feature.RankMulti)] KeyType key, [Payload(Payload.Value)] ValueType value, [Payload(Payload.Value)] ISetValue <ValueType> enumerator, [Payload(Payload.Value)] uint version, [Feature(Feature.Rank, Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] int xStart, [Feature(Feature.RankMulti, Feature.Range, Feature.Range2)][Widen] int xLength, [Feature(Feature.Range2)][Widen] int yStart, [Feature(Feature.Range2)][Widen] int yLength) { this.key = key; this.value = value; this.xStart = xStart; this.xLength = xLength; this.yStart = yStart; this.yLength = yLength; this.enumerator = enumerator; this.version = version; }
public static ISetValue CreateMethodSetterWrapper <TTarget, TValue>(MethodInfo methodInfo) { if (methodInfo == null) { throw new ArgumentNullException("methodInfo is null"); } if (methodInfo.GetParameters().Length != 1) { throw new NotSupportedException("方法参数数量必须为 1"); } ISetValue setter = null; if (_methodSettersCache.TryGetValue(methodInfo, out setter)) { return(setter); } setter = new SetterWrapper <TTarget, TValue>(methodInfo); _methodSettersCache[methodInfo] = setter; return(setter); }
private void DoPropertyBind(VMBehaviour vm, GameObject obj) { if (this.Component == null) { Debugger.LogError("DataBinder", obj.name + " component null."); return; } if (string.IsNullOrEmpty(this.Property)) { Debugger.LogError("DataBinder", obj.name + " property empty."); return; } if (componentType == null) { componentType = this.Component.GetType(); componentReflection = ReflectionCache.Singleton[componentType]; } PropertyInfo propertyInfo = componentReflection.GetProperty(this.Property); if (propertyInfo == null || propertyInfo.GetSetMethod() == null) { Debugger.LogError("DataBinder", obj.name + " property null or not support."); return; } Type propertyType = propertyInfo.PropertyType; if (!CheckDataTypeValid(propertyType, obj)) { return; } ISetValue propertySetter = SetterWrapper.CreatePropertySetterWrapper(propertyInfo); if (propertySetter == null) { return; } // 数据单向绑定 this.SetValueHandler = delegate(IData source) { object value = this.Source.FastGetValue(); if (this.Converter != null) { value = this.Converter.Convert(value, propertyType, this.Definer.ConverterParameter, vm); } propertySetter.Set(this.Component, value); // ToggleGroup 特殊处理 if (Toggle_Type.IsAssignableFrom(componentType) && this.Property.Equals("isOn")) { Toggle t = this.Component as Toggle; if (t.group != null && t.isOn) { try { t.group.NotifyToggleOn(t); } catch (System.Exception) { } } } }; this.Source.AddValueChangedListener(this.SetValueHandler); this.SetValueHandler.Invoke(this.Source); // 可交互组件的双向绑定 if (Toggle_Type.IsAssignableFrom(componentType) && this.Property.Equals("isOn")) { this.ValueChangedHandler = new UnityAction <bool>(delegate(bool arg) { if (this.Converter != null) { object value = this.Converter.ConvertBack(arg, this.Source.GetBindDataType(), this.Definer.ConverterParameter, vm); this.Source.FastSetValue(value); } else { (this.Source as BaseData <bool>).Set(arg); } }); (this.Component as Toggle).onValueChanged.AddListener((UnityAction <bool>) this.ValueChangedHandler); } if (Input_Type.IsAssignableFrom(componentType) && this.Property.Equals("text")) { this.ValueChangedHandler = new UnityAction <string>(delegate(string arg) { if (this.Converter != null) { object value = this.Converter.ConvertBack(arg, this.Source.GetBindDataType(), this.Definer.ConverterParameter, vm); this.Source.FastSetValue(value); } else { (this.Source as BaseData <string>).Set(arg); } }); (this.Component as InputField).onValueChanged.AddListener((UnityAction <string>) this.ValueChangedHandler); } if (Dropdown_Type.IsAssignableFrom(componentType) && this.Property.Equals("value")) { this.ValueChangedHandler = new UnityAction <int>(delegate(int arg) { if (this.Converter != null) { object value = this.Converter.ConvertBack(arg, this.Source.GetBindDataType(), this.Definer.ConverterParameter, vm); this.Source.FastSetValue(value); } else { (this.Source as BaseData <int>).Set(arg); } }); (this.Component as Dropdown).onValueChanged.AddListener((UnityAction <int>) this.ValueChangedHandler); } if (Slider_Type.IsAssignableFrom(componentType) && this.Property.Equals("value")) { this.ValueChangedHandler = new UnityAction <float>(delegate(float arg) { if (this.Converter != null) { object value = this.Converter.ConvertBack(arg, this.Source.GetBindDataType(), this.Definer.ConverterParameter, vm); this.Source.FastSetValue(value); } else { (this.Source as BaseData <float>).Set(arg); } }); (this.Component as Slider).onValueChanged.AddListener((UnityAction <float>) this.ValueChangedHandler); } }
public static void Test() { int count = 1000000; OrderInfo order = new OrderInfo() { OrderID = 22 }; PropertyInfo propertyInfo = order.GetType().GetProperty("OrderID"); Console.Write("反射调用:"); Stopwatch watch1 = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { GetPropertyValue(order, propertyInfo); } watch1.Stop(); Console.WriteLine(watch1.Elapsed.ToString()); Console.Write("普通调用:"); Stopwatch watch2 = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { order.OrderID = 11; } watch2.Stop(); Console.WriteLine(watch2.Elapsed.ToString()); Console.Write("Emit调用:"); Action <object, object> setter1 = CreatePropertySetter_Emit(propertyInfo); Stopwatch watch3 = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { setter1(order, 11); } watch3.Stop(); Console.WriteLine(watch3.Elapsed.ToString()); Console.Write("委托调用:"); Action <OrderInfo, int> setter2 = (Action <OrderInfo, int>)Delegate.CreateDelegate(typeof(Action <OrderInfo, int>), null, propertyInfo.GetSetMethod()); Stopwatch watch4 = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { setter2(order, 11); } watch4.Stop(); Console.WriteLine(watch4.Elapsed.ToString()); Console.Write("泛型调用:"); SetterHelper <OrderInfo, int> setter3 = new SetterHelper <OrderInfo, int>(propertyInfo); Stopwatch watch5 = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { setter3.SetValue(order, 11); } watch5.Stop(); Console.WriteLine(watch5.Elapsed.ToString()); Console.Write("通用接口调用:"); ISetValue setter4 = SetterHelper <int, int> .CreatePropertySetterHelper(propertyInfo); Stopwatch watch6 = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { setter4.Set(order, 11); } watch5.Stop(); Console.WriteLine(watch6.Elapsed.ToString()); }
private void loadFunctions() { IntPtr pGetProcessList = GetProcAddress(libInst, "IGetProcessList"); IntPtr pOpenProcess = GetProcAddress(libInst, "IOpenProcess"); IntPtr pResetTable = GetProcAddress(libInst, "IResetTable"); IntPtr pAddScript = GetProcAddress(libInst, "IAddScript"); IntPtr pRemoveRecord = GetProcAddress(libInst, "IRemoveRecord"); IntPtr pActivateRecord = GetProcAddress(libInst, "IActivateRecord"); IntPtr pApplyFreeze = GetProcAddress(libInst, "IApplyFreeze"); IntPtr pAddAddressManually = GetProcAddress(libInst, "IAddAddressManually"); IntPtr pGetValue = GetProcAddress(libInst, "IGetValue"); IntPtr pSetValue = GetProcAddress(libInst, "ISetValue"); IntPtr pProcessAddress = GetProcAddress(libInst, "IProcessAddress"); IntPtr pInitMemoryScanner = GetProcAddress(libInst, "IInitMemoryScanner"); IntPtr pNewScan = GetProcAddress(libInst, "INewScan"); IntPtr pConfigScanner = GetProcAddress(libInst, "IConfigScanner"); IntPtr pFirstScan = GetProcAddress(libInst, "IFirstScan"); IntPtr pNextScan = GetProcAddress(libInst, "INextScan"); IntPtr pCountAddressesFound = GetProcAddress(libInst, "ICountAddressesFound"); IntPtr pGetAddress = GetProcAddress(libInst, "IGetAddress"); IntPtr pInitFoundList = GetProcAddress(libInst, "IInitFoundList"); IntPtr pResetValues = GetProcAddress(libInst, "IResetValues"); IntPtr pGetBinarySize = GetProcAddress(libInst, "IGetBinarySize"); iGetProcessList = (IGetProcessList)Marshal.GetDelegateForFunctionPointer(pGetProcessList, typeof(IGetProcessList)); iOpenProcess = (IOpenProcess)Marshal.GetDelegateForFunctionPointer(pOpenProcess, typeof(IOpenProcess)); iResetTable = (IResetTable)Marshal.GetDelegateForFunctionPointer(pResetTable, typeof(IResetTable)); iAddScript = (IAddScript)Marshal.GetDelegateForFunctionPointer(pAddScript, typeof(IAddScript)); iRemoveRecord = (IRemoveRecord)Marshal.GetDelegateForFunctionPointer(pRemoveRecord, typeof(IRemoveRecord)); iActivateRecord = (IActivateRecord)Marshal.GetDelegateForFunctionPointer(pActivateRecord, typeof(IActivateRecord)); iApplyFreeze = (IApplyFreeze)Marshal.GetDelegateForFunctionPointer(pApplyFreeze, typeof(IApplyFreeze)); iAddAddressManually = (IAddAddressManually)Marshal.GetDelegateForFunctionPointer(pAddAddressManually, typeof(IAddAddressManually)); iGetValue = (IGetValue)Marshal.GetDelegateForFunctionPointer(pGetValue, typeof(IGetValue)); iSetValue = (ISetValue)Marshal.GetDelegateForFunctionPointer(pSetValue, typeof(ISetValue)); iProcessAddress = (IProcessAddress)Marshal.GetDelegateForFunctionPointer(pProcessAddress, typeof(IProcessAddress)); iInitMemoryScanner = (IInitMemoryScanner)Marshal.GetDelegateForFunctionPointer(pInitMemoryScanner, typeof(IInitMemoryScanner)); iNewScan = (INewScan)Marshal.GetDelegateForFunctionPointer(pNewScan, typeof(INewScan)); iConfigScanner = (IConfigScanner)Marshal.GetDelegateForFunctionPointer(pConfigScanner, typeof(IConfigScanner)); iFirstScan = (IFirstScan)Marshal.GetDelegateForFunctionPointer(pFirstScan, typeof(IFirstScan)); iNextScan = (INextScan)Marshal.GetDelegateForFunctionPointer(pNextScan, typeof(INextScan)); iCountAddressesFound = (ICountAddressesFound)Marshal.GetDelegateForFunctionPointer(pCountAddressesFound, typeof(ICountAddressesFound)); iGetAddress = (IGetAddress)Marshal.GetDelegateForFunctionPointer(pGetAddress, typeof(IGetAddress)); iInitFoundList = (IInitFoundList)Marshal.GetDelegateForFunctionPointer(pInitFoundList, typeof(IInitFoundList)); iResetValues = (IResetValues)Marshal.GetDelegateForFunctionPointer(pResetValues, typeof(IResetValues)); iGetBinarySize = (IGetBinarySize)Marshal.GetDelegateForFunctionPointer(pGetBinarySize, typeof(IGetBinarySize)); }
public MultiDataPointBindingObject(ISetValue target) { this.targetElement = target; }
public static void Test() { Console.WriteLine(System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion()); int count = 1000000; OrderInfo testObj = new OrderInfo(); PropertyInfo propInfo = typeof(OrderInfo).GetProperty("OrderID"); Console.Write("直接访问花费时间: "); Stopwatch watch1 = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { testObj.OrderID = 123; } watch1.Stop(); Console.WriteLine(watch1.Elapsed.ToString()); SetValueDelegate setter2 = DynamicMethodFactory.CreatePropertySetter(propInfo); Console.Write("EmitSet花费时间: "); Stopwatch watch2 = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { setter2(testObj, 123); } watch2.Stop(); Console.WriteLine(watch2.Elapsed.ToString()); Console.Write("纯反射花费时间: "); Stopwatch watch3 = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { propInfo.SetValue(testObj, 123, null); } watch3.Stop(); Console.WriteLine(watch3.Elapsed.ToString()); Console.WriteLine("----------------------------------"); Console.WriteLine("{0} / {1} = {2}", watch3.Elapsed.ToString(), watch1.Elapsed.ToString(), watch3.Elapsed.TotalMilliseconds / watch1.Elapsed.TotalMilliseconds); Console.WriteLine("{0} / {1} = {2}", watch3.Elapsed.ToString(), watch2.Elapsed.ToString(), watch3.Elapsed.TotalMilliseconds / watch2.Elapsed.TotalMilliseconds); Console.WriteLine("{0} / {1} = {2}", watch2.Elapsed.ToString(), watch1.Elapsed.ToString(), watch2.Elapsed.TotalMilliseconds / watch1.Elapsed.TotalMilliseconds); Console.Write("泛型委托花费时间: "); SetterWrapper <OrderInfo, int> setter3 = new SetterWrapper <OrderInfo, int>(propInfo); Stopwatch watch4 = Stopwatch.StartNew(); for (int i = 0; i < count; i++) { setter3.SetValue(testObj, 123); } watch4.Stop(); Console.WriteLine(watch4.Elapsed.ToString()); Console.Write("通用接口花费时间: "); ISetValue setter4 = GetterSetterFactory.CreatePropertySetterWrapper(propInfo); Stopwatch watch5 = Stopwatch.StartNew(); watch5.Start(); for (int i = 0; i < count; i++) { setter4.Set(testObj, 123); } watch5.Stop(); Console.WriteLine(watch5.Elapsed.ToString()); }