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)、实体、方法);