猿问

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

我正在使用带有实体框架核心的.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# 中也可能吗?


BIG阳
浏览 149回答 2
2回答

慕码人8056858

正如有人在评论中指出的那样,您应该使用泛型: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){&nbsp; &nbsp; &nbsp;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()&nbsp; &nbsp; .SelectMany(s => s.GetTypes())&nbsp; &nbsp; .Where(p => type.IsAssignableFrom(p));2.这样调用GetTableData方法:MethodInfo method = GetType.GetMethod("GetTableData ");foreach (var entityType in types){&nbsp; &nbsp; MethodInfo genericMethod = method.MakeGenericMethod(entityType);&nbsp; &nbsp; genericMethod.Invoke(this, null);}

慕田峪9158850

我的解决方案如下;MethodInfo methodInfo = typeof(CacheSettings).GetMethod("GetTableData");string[] tablesToBeCached&nbsp; = { "Student", "Class", "Teacher" };object[] parameters = new object[] { myDBContextObj };foreach(var tblToBeCached in tablesToBeCached){&nbsp; &nbsp; string key = $"{tblToBeCached}";&nbsp; &nbsp; MethodInfo getTableDataMethod = methodInfo.MakeGenericMethod(Type.GetType($"Namespace.{tblToBeCached}, AssemblyName"));&nbsp; &nbsp; 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{&nbsp; &nbsp;return dbContext.Set<T>();}
随时随地看视频慕课网APP
我要回答