C# 泛型方法-我可以避免在代码中使用反射吗?
假设我有以下方法:C# 泛型方法-我可以避免在代码中使用反射吗?,c#,generics,C#,Generics,假设我有以下方法: private static void SetLastModifiedTimeUser<TEntity>(TEntity entity) where TEntity : class { PropertyInfo propertyInfo; propertyInfo = entity.GetType().GetProperty("LastModifiedUser"); if (propertyInfo != null) pr
private static void SetLastModifiedTimeUser<TEntity>(TEntity entity) where TEntity : class
{
PropertyInfo propertyInfo;
propertyInfo = entity.GetType().GetProperty("LastModifiedUser");
if (propertyInfo != null)
propertyInfo.SetValue(entity, IdentityHelper.UserName, null);
}
私有静态void SetLastModifiedTimeUser(TEntity实体),其中TEntity:class
{
PropertyInfo PropertyInfo;
propertyInfo=entity.GetType().GetProperty(“LastModifiedUser”);
if(propertyInfo!=null)
propertyInfo.SetValue(实体,IdentityHelper.UserName,null);
}
如您所见,该方法接受泛型类型。传递给此方法的每个类都将包含一个名为“LastModifiedUser”的属性。有没有一种方法可以在不使用反射的情况下访问此属性?我不认为有,但我想我应该问一下。是的,如果所有实体都有
LastModifiedUser
属性,那么您可以让所有实体从基类继承,或者实现类似
public interface IModifyable
{
string LastModifiedUser { get; set; }
}
然后只需添加此约束(或使您的方法非泛型,接受IModifyable
)
您的代码如下所示:
private static void SetLastModifiedTimeUser<TEntity>(TEntity entity)
where TEntity : class, IModifyable
{
entity.LastModifiedUser = IdentityHelper.UserName;
}
私有静态void SetLastModifiedTimeUser(tenty实体)
其中tenty:类,IModifyable
{
entity.LastModifiedUser=IdentityHelper.UserName;
}
是的,如果所有实体都具有LastModifiedUser
属性,则可以使所有实体从基类继承,或实现类似
public interface IModifyable
{
string LastModifiedUser { get; set; }
}
然后只需添加此约束(或使您的方法非泛型,接受IModifyable
)
您的代码如下所示:
private static void SetLastModifiedTimeUser<TEntity>(TEntity entity)
where TEntity : class, IModifyable
{
entity.LastModifiedUser = IdentityHelper.UserName;
}
私有静态void SetLastModifiedTimeUser(tenty实体)
其中tenty:类,IModifyable
{
entity.LastModifiedUser=IdentityHelper.UserName;
}
让类从定义LastModifiedUser
属性的接口继承
public interface ILastModifiedUser
{
public string LastModifiedUser { get; set; }
}
public static class LastModifiedTimeUserSetter
{
public static void Set<TEntity>(TEntity entity)
{
var action = (Action<TEntity>) Properties.GetOrAdd(typeof(TEntity), CreateDynamicSetMethodDelegate);
if(action != null)
action(entity);
}
static Delegate CreateDynamicSetMethodDelegate(Type type)
{
return CreateDynamicSetMethod(type).CreateDelegate(GetActionType(type));
}
static DynamicMethod CreateDynamicSetMethod(Type typeWithProperty)
{
var methodBuilder = new DynamicMethod(
"Dynamic_" + typeWithProperty.FullName + "_SetLastModifiedUser",
typeof (void),
new[] {typeWithProperty});
EmitSimpleAssignmentMethod(methodBuilder,
GetIdentityHelperUserNameGetMethod(),
GetPropertySetMethod(typeWithProperty));
return methodBuilder;
}
static MethodInfo GetIdentityHelperUserNameGetMethod()
{
return typeof(IdentityHelper).GetProperty("UserName").GetGetMethod();
}
static MethodInfo GetPropertySetMethod(Type type)
{
var prop = type.GetProperty("LastModifiedUser");
if (prop == null)
return null;
return prop.GetSetMethod();
}
static void EmitSimpleAssignmentMethod(DynamicMethod methodBuilder, MethodInfo getMethod, MethodInfo setMethod)
{
var il = methodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.EmitCall(OpCodes.Call, getMethod, null);
il.EmitCall(OpCodes.Call, setMethod, null);
il.Emit(OpCodes.Ret);
}
static Type GetActionType(Type type)
{
return typeof (Action<string>).GetGenericTypeDefinition().MakeGenericType(type);
}
static readonly ConcurrentDictionary<Type, Delegate> Properties = new ConcurrentDictionary<Type, Delegate>();
}
将方法声明更改为
private static void SetLastModifiedTimeUser(ILastModifiedUser entity)
让您的类从定义
LastModifiedUser
属性的接口继承
public interface ILastModifiedUser
{
public string LastModifiedUser { get; set; }
}
public static class LastModifiedTimeUserSetter
{
public static void Set<TEntity>(TEntity entity)
{
var action = (Action<TEntity>) Properties.GetOrAdd(typeof(TEntity), CreateDynamicSetMethodDelegate);
if(action != null)
action(entity);
}
static Delegate CreateDynamicSetMethodDelegate(Type type)
{
return CreateDynamicSetMethod(type).CreateDelegate(GetActionType(type));
}
static DynamicMethod CreateDynamicSetMethod(Type typeWithProperty)
{
var methodBuilder = new DynamicMethod(
"Dynamic_" + typeWithProperty.FullName + "_SetLastModifiedUser",
typeof (void),
new[] {typeWithProperty});
EmitSimpleAssignmentMethod(methodBuilder,
GetIdentityHelperUserNameGetMethod(),
GetPropertySetMethod(typeWithProperty));
return methodBuilder;
}
static MethodInfo GetIdentityHelperUserNameGetMethod()
{
return typeof(IdentityHelper).GetProperty("UserName").GetGetMethod();
}
static MethodInfo GetPropertySetMethod(Type type)
{
var prop = type.GetProperty("LastModifiedUser");
if (prop == null)
return null;
return prop.GetSetMethod();
}
static void EmitSimpleAssignmentMethod(DynamicMethod methodBuilder, MethodInfo getMethod, MethodInfo setMethod)
{
var il = methodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.EmitCall(OpCodes.Call, getMethod, null);
il.EmitCall(OpCodes.Call, setMethod, null);
il.Emit(OpCodes.Ret);
}
static Type GetActionType(Type type)
{
return typeof (Action<string>).GetGenericTypeDefinition().MakeGenericType(type);
}
static readonly ConcurrentDictionary<Type, Delegate> Properties = new ConcurrentDictionary<Type, Delegate>();
}
将方法声明更改为
private static void SetLastModifiedTimeUser(ILastModifiedUser entity)
如果不能修改所有类以实现公共接口,则可以使用
dynamic
private static void SetLastModifiedTimeUser<TEntity>(TEntity entity) where TEntity : class
{
dynamic d = entity;
d.LastModifiedUser = IdentityHelper.UserName;
}
私有静态void SetLastModifiedTimeUser(TEntity实体),其中TEntity:class
{
动态d=实体;
d、 LastModifiedUser=IdentityHelper.UserName;
}
否则,它就像所示的那样简单。如果不能修改所有类来实现一个公共接口,那么可以使用
动态
private static void SetLastModifiedTimeUser<TEntity>(TEntity entity) where TEntity : class
{
dynamic d = entity;
d.LastModifiedUser = IdentityHelper.UserName;
}
私有静态void SetLastModifiedTimeUser(TEntity实体),其中TEntity:class
{
动态d=实体;
d、 LastModifiedUser=IdentityHelper.UserName;
}
<> P> >如果您不能向对象添加接口,请考虑此方法。
第一次遇到每个类型(tenty)时,它会查找属性并获取属性的SetMethod。然后,在每次使用时,它创建并调用该方法
var one = new EntityOne();
LastModifiedTimeUserSetter.Set(one);
Console.WriteLine(one.LastModifiedUser);
public static class LastModifiedTimeUserSetter
{
public static void Set<TEntity>(TEntity entity)
{
var method = Properties.GetOrAdd(typeof (TEntity), GetSetMethod);
var action = (Action<string>) Delegate.CreateDelegate(typeof (Action<string>), entity, method);
action(IdentityHelper.UserName);
}
static MethodInfo GetSetMethod(Type type)
{
var prop = type.GetProperty("LastModifiedUser");
if (prop == null)
return null;
return prop.GetSetMethod();
}
static readonly ConcurrentDictionary<Type, MethodInfo> Properties = new ConcurrentDictionary<Type, MethodInfo>();
}
var one=newentityone();
LastModifiedTimeUserSetter.Set(一个);
Console.WriteLine(1.LastModifiedUser);
公共静态类LastModifiedTimeUserSetter
{
公共静态无效集(TEntity实体)
{
var method=Properties.GetOrAdd(typeof(tenty),GetSetMethod);
var action=(action)Delegate.CreateDelegate(typeof(action)、实体、方法);
操作(identityhelp.UserName);
}
静态MethodInfo GetSetMethod(类型)
{
var prop=type.GetProperty(“LastModifiedUser”);
if(prop==null)
返回null;
返回prop.GetSetMethod();
}
静态只读ConcurrentDictionary属性=新建ConcurrentDictionary();
}
进一步
有一种方法可以通过使用进一步提高性能。以及构建一个获取实体并设置属性的方法
public interface ILastModifiedUser
{
public string LastModifiedUser { get; set; }
}
public static class LastModifiedTimeUserSetter
{
public static void Set<TEntity>(TEntity entity)
{
var action = (Action<TEntity>) Properties.GetOrAdd(typeof(TEntity), CreateDynamicSetMethodDelegate);
if(action != null)
action(entity);
}
static Delegate CreateDynamicSetMethodDelegate(Type type)
{
return CreateDynamicSetMethod(type).CreateDelegate(GetActionType(type));
}
static DynamicMethod CreateDynamicSetMethod(Type typeWithProperty)
{
var methodBuilder = new DynamicMethod(
"Dynamic_" + typeWithProperty.FullName + "_SetLastModifiedUser",
typeof (void),
new[] {typeWithProperty});
EmitSimpleAssignmentMethod(methodBuilder,
GetIdentityHelperUserNameGetMethod(),
GetPropertySetMethod(typeWithProperty));
return methodBuilder;
}
static MethodInfo GetIdentityHelperUserNameGetMethod()
{
return typeof(IdentityHelper).GetProperty("UserName").GetGetMethod();
}
static MethodInfo GetPropertySetMethod(Type type)
{
var prop = type.GetProperty("LastModifiedUser");
if (prop == null)
return null;
return prop.GetSetMethod();
}
static void EmitSimpleAssignmentMethod(DynamicMethod methodBuilder, MethodInfo getMethod, MethodInfo setMethod)
{
var il = methodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.EmitCall(OpCodes.Call, getMethod, null);
il.EmitCall(OpCodes.Call, setMethod, null);
il.Emit(OpCodes.Ret);
}
static Type GetActionType(Type type)
{
return typeof (Action<string>).GetGenericTypeDefinition().MakeGenericType(type);
}
static readonly ConcurrentDictionary<Type, Delegate> Properties = new ConcurrentDictionary<Type, Delegate>();
}
公共静态类LastModifiedTimeUserSetter
{
公共静态无效集(TEntity实体)
{
var action=(action)Properties.GetOrAdd(typeof(tenty),CreateDynamicSetMethodDelegate);
如果(操作!=null)
行动(实体);
}
静态委托CreateDynamicSetMethodDelegate(类型)
{
返回CreateDynamicSetMethod(类型).CreateDelegate(GetActionType(类型));
}
静态动态方法CreateDynamicSetMethod(类型typeWithProperty)
{
var methodBuilder=新的DynamicMethod(
“动态”+类型WithProperty.FullName+“\u SetLastModifiedUser”,
类型(无效),
新[]{typeWithProperty});
EmitSimpleAssignmentMethod(methodBuilder,
GetIdentityHelpPerUserNameGetMethod(),
GetPropertySetMethod(typeWithProperty));
返回方法生成器;
}
静态MethodInfo GetIdentityHelpPerUserNameGetMethod()
{
返回typeof(identityhelp).GetProperty(“用户名”).getMethod();
}
静态MethodInfo GetPropertySetMethod(类型)
{
var prop=type.GetProperty(“LastModifiedUser”);
if(prop==null)
返回null;
返回prop.GetSetMethod();
}
静态void EmitSimpleAssignmentMethod(DynamicMethodMethodBuilder、MethodInfo getMethod、MethodInfo setMethod)
{
var il=methodBuilder.GetILGenerator();
il.Emit(操作码.Ldarg_0);
EmitCall(OpCodes.Call,getMethod,null);
EmitCall(OpCodes.Call,setMethod,null);
发射(操作码Ret);
}
静态类型GetActionType(类型类型)
{
返回typeof(Action).GetGenericTypeDefinition().MakeGenericType(type);
}
静态只读ConcurrentDictionary属性=新建ConcurrentDictionary();
}
参见.
< P>如果不能向对象添加接口,请考虑此方法。
第一次遇到每个类型(tenty)时,它会查找属性并获取属性的SetMethod。然后,在每次使用时,它创建并调用该方法
var one = new EntityOne();
LastModifiedTimeUserSetter.Set(one);
Console.WriteLine(one.LastModifiedUser);
public static class LastModifiedTimeUserSetter
{
public static void Set<TEntity>(TEntity entity)
{
var method = Properties.GetOrAdd(typeof (TEntity), GetSetMethod);
var action = (Action<string>) Delegate.CreateDelegate(typeof (Action<string>), entity, method);
action(IdentityHelper.UserName);
}
static MethodInfo GetSetMethod(Type type)
{
var prop = type.GetProperty("LastModifiedUser");
if (prop == null)
return null;
return prop.GetSetMethod();
}
static readonly ConcurrentDictionary<Type, MethodInfo> Properties = new ConcurrentDictionary<Type, MethodInfo>();
}
var one=newentityone();
LastModifiedTimeUserSetter.Set(一个);
Console.WriteLine(1.LastModifiedUser);
公共静态类LastModifiedTimeUserSetter
{
公共静态无效集(TEntity实体)
{
var method=Properties.GetOrAdd(typeof(tenty),GetSetMethod);
var action=(action)Delegate.CreateDelegate(typeof(action)、实体、方法);