비반사는 유형적으로 동적Property에 값을 부여하고 값을 부여하지 않습니다.
해당되는 사항:
불확실한 대상을 위해 알 수 없는 Property나 여러 개의 Property에 동적으로 값과 값을 부여합니다
주요 특징:
비 Property.GetValue 또는 Property.SetValue, 위탁 대리 캐시 메커니즘을 사용합니다.
따라서 다음과 같이 사용할 수 있습니다.
// Entity
var instance = new Topic();
// Property Dictionary
var propDic = new InstancePropertyDictionary(instance);
// Object
propDic.SetValue(" ",Int32 Stirng ...);
//
Int32 int32Value = propDic.GetInt32(" ");
string stringValue = propDic.GetString(" ");
다음은 모두 이루어진 코드로 한 종류로 직접 사용할 수 있다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Lx
{
/// <summary>
/// Instance / ( )
/// </summary>
class InstancePropertyDictionary
{
/// <summary>
/// Get
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <returns></returns>
delegate TResult Get<TResult>();
/// <summary>
/// Set
/// </summary>
/// <typeparam name="TValue"></typeparam>
/// <param name="value"></param>
delegate void Set<TValue>(TValue value);
/// <summary>
/// Instance
/// </summary>
object Target;
/// <summary>
/// Instance
/// </summary>
Type TargetType;
public InstancePropertyDictionary(object instance)
{
this.Target = instance;
this.TargetType = Target.GetType();
}
#region Set
/// <summary>
/// Key
/// Value
/// </summary>
Dictionary<string, Set<Int32>> setInt32Dic = new Dictionary<string, Set<Int32>>();
Dictionary<string, Set<string>> setStringDic = new Dictionary<string, Set<string>>();
#endregion
#region Get
Dictionary<string, Get<Int32>> getInt32Dic = new Dictionary<string, Get<Int32>>();
Dictionary<string, Get<string>> getStringDic = new Dictionary<string, Get<string>>();
#endregion
/// <summary>
///
/// </summary>
public void LoadProperty(params string[] names)
{
var props = TargetType.GetProperties();
foreach (var name in names)
{
foreach (var prop in props)
{
if (prop.Name == name)
{
CreateGetSet(prop);
}
}
}
}
/// <summary>
/// Getter/Setter
/// </summary>
/// <param name="property"></param>
void CreateGetSet(PropertyInfo property)
{
string propName = property.Name;
var propType = property.PropertyType;
var propSetMethod = property.GetSetMethod();
var propGetMethod = property.GetGetMethod();
if (typeof(Int32) == propType)
{
var set = CreateSet<Int32>(propSetMethod);
setInt32Dic.Add(propName, set);
var get = CreateGet<Int32>(propGetMethod);
getInt32Dic.Add(propName, get);
}
else if (typeof(string) == propType)
{
var set = CreateSet<string>(propSetMethod);
setStringDic.Add(propName, set);
var get = CreateGet<string>(propGetMethod);
getStringDic.Add(propName, get);
}
// else if
}
Set<T> CreateSet<T>(MethodInfo methodInfo)
{
var result = (Set<T>)Delegate.CreateDelegate(typeof(Set<T>), Target, methodInfo);
return result;
}
Get<T> CreateGet<T>(MethodInfo methodInfo)
{
var result = (Get<T>)Delegate.CreateDelegate(typeof(Get<T>), Target, methodInfo);
return result;
}
/// <summary>
/// Set
/// </summary>
/// <param name="propertyName"></param>
/// <param name="value"></param>
public void SetValue(string propertyName, Int32 value)
{
//
var dg = setInt32Dic[propertyName];
dg.Invoke(value);
}
public void SetValue(string propertyName, string value)
{
var dg = setStringDic[propertyName];
dg.Invoke(value);
}
/// <summary>
/// Get
/// </summary>
/// <param name="propertyName"></param>
/// <returns></returns>
public Int32 GetInt32(string propertyName)
{
var dg = getInt32Dic[propertyName];
return dg.Invoke();
}
public string GetString(string propertyName)
{
var dg = getStringDic[propertyName];
return dg.Invoke();
}
}
}
Expression Tree를 어떻게 사용하는지, 프록시 위임을 만드는 것보다 성능이 좋은지 몰라서 붙여놨습니다. 댓글 토론을 환영합니다.
부록:
.NET의 Delegate.CreateDelegate 방법의 실현
[SecuritySafeCritical]
public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
if (method == null)
{
throw new ArgumentNullException("method");
}
if (!(type is RuntimeType))
{
throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "type");
}
RuntimeMethodInfo info = method as RuntimeMethodInfo;
if (info == null)
{
throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "method");
}
Type baseType = type.BaseType;
if ((baseType == null) || (baseType != typeof(MulticastDelegate)))
{
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), "type");
}
Delegate delegate2 = InternalAlloc(type.TypeHandle.GetRuntimeType());
if (delegate2.BindToMethodInfo(firstArgument, info.MethodHandle.GetMethodInfo(), info.GetDeclaringTypeInternal().TypeHandle.GetRuntimeType(), DelegateBindingFlags.RelaxedSignature))
{
return delegate2;
}
if (throwOnBindFailure)
{
throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
}
return null;
}
나는 이 종류에서 성능에 영향을 주는 관건은Delegate에 있다고 생각한다.Create Delegate 방법의 구체적인 방법은 어떻게 하는 것입니까, 아니면Methodinfo입니다.Invoke(object, object[])입니까?
Reflecter 반사로 BindToMethodInfo가 extern으로 표시된 것을 발견했습니다.
본문에서 말한'비반사'에 대한 반대:
어떤 사람이 반사용으로 썼다고 대답했다.
나는 반사적인 방식으로'동적Property에 값을 부여하고 값을 얻는다'고 말하지 않는다. 본고의 제목도 오도하지 않았겠지?
에서
CreateSet
이 두 가지 방법의 실현은 이미 반사를 쓰는 것이 아니라 위탁을 하고 있다는 것을 알 수 있다
앞에 반사된 부분은Property의GetMethod와SetMethod를 가져와서 강력한 종류의 의뢰를 만드는 데 사용됩니다.따라서 Property에 값을 부여할 때 반사가 존재하지 않습니다.그리고 Secmoo가 답장하는 테스트 결과를 볼 수 있다. 만약에 수치를 추출하고 값을 부여하는 과정에서 반사 메커니즘이 관련된다면 Expression의 성능을 초과할 수 없다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.