为了账号安全,请及时绑定邮箱和手机立即绑定

在 C# 中将类型传递给函数

在 C# 中将类型传递给函数

C#
BIG阳 2023-12-17 10:12:31
我正在使用带有实体框架核心的.net core 2.1。我的项目中定义了不同的模型/实体/类型。例如学生、班级、老师。我正在获取这些模型的表数据以在我的缓存中设置。此刻,我正在做这件事;string[] tablesToBeCached  = { "Student", "Class", "Teacher" };foreach(var table in tablesToBeCached){     cache.Set(key, GetTableData(dbContext, table));}函数GetTableData()定义如下;public IEnumerable<object> GetTableData(DBContext dbContext, string tableName){      switch (tableName)      {          case "Student":              return dbContext.Student;          case "Class":              return dbContext.Class;          case "Teacher":              return dbContext.Teacher;          default:              return null;       }  }我希望这段代码既聪明又简短。我尝试遵循,但没有成功; (错误是“x”是一个变量,但像类型一样使用)List<object> entities = new List<object> { typeof(Student), typeof(Class), typeof(Teacher) };entities.ForEach(x => GetTableData(x, dbContext));public IEnumerable<object> GetTableData(object x, DBContext dbContext){     return dbContext.Set<x>();}有人可以帮忙吗?在 C# 中也可能吗?
查看完整描述

2 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

正如有人在评论中指出的那样,您应该使用泛型:


cache.Set(key1, GetTableData<Student>(dbContext));

cache.Set(key2, GetTableData<Class>(dbContext));

cache.Set(key3, GetTableData<Teacher>(dbContext));



public static IEnumerable<T> GetTableData<T> (DBContext dbContext)

{

     return dbContext.Set<T>();

}

为了避免为每个实体编写相同的代码 (cache.Set),您可以使用反射,但您的实体应该实现某种通用接口或基类。


例如,假设您的实体实现一个通用接口IEntity:


interface IEntity {}


class Student: IEntity {}


class Teacher: IEntity {}

然后你可以


1 检索所有实现IEntity的类型:


var type = typeof(IEntity);

var types = AppDomain.CurrentDomain.GetAssemblies()

    .SelectMany(s => s.GetTypes())

    .Where(p => type.IsAssignableFrom(p));

2.这样调用GetTableData方法:


MethodInfo method = GetType.GetMethod("GetTableData ");


foreach (var entityType in types)

{

    MethodInfo genericMethod = method.MakeGenericMethod(entityType);

    genericMethod.Invoke(this, null);

}


查看完整回答
反对 回复 2023-12-17
?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

我的解决方案如下;


MethodInfo methodInfo = typeof(CacheSettings).GetMethod("GetTableData");

string[] tablesToBeCached  = { "Student", "Class", "Teacher" };

object[] parameters = new object[] { myDBContextObj };


foreach(var tblToBeCached in tablesToBeCached)

{

    string key = $"{tblToBeCached}";

    MethodInfo getTableDataMethod = methodInfo.MakeGenericMethod(Type.GetType($"Namespace.{tblToBeCached}, AssemblyName"));

    cache.Set(key, getTableDataMethod.Invoke(null, parameters));

}


and the GetTableData() method is just one liner (Happy days 😊)


public static IEnumerable<T> GetTableData<T>(MyDBContext dbContext) where T : class

{

   return dbContext.Set<T>();

}


查看完整回答
反对 回复 2023-12-17
  • 2 回答
  • 0 关注
  • 133 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信