C# 反射:如何从使用反射调用的方法中获得结果(并对其执行foreach)?
我想从不同的存储库调用一些方法,并将相同类型的C# 反射:如何从使用反射调用的方法中获得结果(并对其执行foreach)?,c#,reflection,casting,generic-list,C#,Reflection,Casting,Generic List,我想从不同的存储库调用一些方法,并将相同类型的List作为结果,但我不知道如何在没有硬代码的情况下转换结果,也不知道如何在此结果上使用foreach,下面是一个示例: class Person { public string Name { get; set; } } class Animal { public string Name { get; set; } } class PersonRepository { public List<Person> G
List
作为结果,但我不知道如何在没有硬代码的情况下转换结果,也不知道如何在此结果上使用foreach
,下面是一个示例:
class Person
{
public string Name { get; set; }
}
class Animal
{
public string Name { get; set; }
}
class PersonRepository
{
public List<Person> GetPersons()
{
List<Person> list = new List<Person>();
//Some processing...
return list;
}
}
class AnimalRepository
{
public List<Animal> GetAnimals()
{
List<Animal> list = new List<Animal>();
//Some processing...
return list;
}
}
public class ReflectionClass
{
public List<T> GetResultFromMethodInvoked<T>(string entityName, string repositoryName, string methodName)
{
List<T> lists = new List<T>();
Type entity_type = Type.GetType("Entities." + entityName + " ,Entities");
Type repository = Type.GetType("Crud." + repositoryName + ", Crud");
MethodInfo method = repository.GetType().GetMethod(methodName);
var r= method.Invoke(repository, parameters);
Convert.ChangeType(r, typeof(List<>).MakeGenericType(new Type[] { entity_type }));
lists = (List<T>)r;
return lists;
}
}
class Program
{
static void Main(string[] args)
{
ReflectionClass reflection = new ReflectionClass();
/* Should have List<Person> as RESULT */
reflection.GetResultFromMethodInvoked("Person", "PersonRepository", "GetPersons");
/* Should have List<Animal> as RESULT */
reflection.GetResultFromMethodInvoked("Animal", "AnimalRepository", "GetAnimals");
}
}
班级人员
{
公共字符串名称{get;set;}
}
类动物
{
公共字符串名称{get;set;}
}
类PersonRepository
{
公众人士名单
{
列表=新列表();
//一些处理。。。
退货清单;
}
}
类动物库
{
公共列表获取动物()
{
列表=新列表();
//一些处理。。。
退货清单;
}
}
公共类ReflectionClass
{
公共列表GetResultFromMethodInvoked(string entityName、string repositoryName、string methodName)
{
列表=新列表();
Type entity_Type=Type.GetType(“Entities.+entityName+”,Entities”);
类型repository=Type.GetType(“Crud.”+repositoryName+”,Crud”);
MethodInfo method=repository.GetType().GetMethod(methodName);
var r=method.Invoke(存储库,参数);
Convert.ChangeType(r,typeof(List).MakeGenericType(新类型[]{entity_Type}));
列表=(列表)r;
退货清单;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
ReflectionClass reflection=新的ReflectionClass();
/*因此应该有一份清单*/
GetResultFromMethodInvoked(“Person”、“PersonRepository”、“GetPersons”);
/*因此应该有一份清单*/
reflection.GetResultFromMethodInvoked(“动物”、“动物存储库”、“GetAnimals”);
}
}
在代码中使用泛型公共列表GetResultFromMethodInvoked(string entityName、string repositoryName、string methodName)
ReflectionClass reflection = new ReflectionClass();
/* Should have List<Person> as RESULT */
List<Person> result = reflection.GetResultFromMethodInvoked<Person>("Person", "PersonRepository", "GetPersons");
ReflectionClass reflection=新的ReflectionClass();
/*因此应该有一份清单*/
List result=reflection.GetResultFromMethodInvoked(“Person”、“PersonRepository”、“GetPersons”);
作为编译器,您不能这样做,因为您不知道运行时的字符串“Person”
表示Person
-类型。您不能期望编译器推断运行时提供的类型(例如,通过其名称)
所以你有三个选择
list
interface MyInterface
{
public string Name { get; set; }
}
class Person : MyInterface
{
public string Name { get; set; }
}
class Animal : MyInterface
{
public string Name { get; set; }
}
现在使用列表的界面:
var result = reflection.GetResultFromMethodInvoked<MyInterface>("Person", "PersonRepository", "GetPersons");
foreach(var o in result)
Console.WriteLine(o.Name);
为了实现这一点,您的方法当然也应该是非泛型的,因为您不能在该方法之外真正使用泛型类型这是不可能的,您不能让编译器推断您在运行时提供的类型。您必须在编译时提供泛型类型参数才能使用强类型。不过,您当然可以将结果强制转换到非泛型
IEnumerable
-接口并进行迭代。或者创建一个接口,让列表中所有可能的类型实现并转换为列表
。Hi@HimBromBeere,我不确定是否理解good,我是C#新手,你能给我一个你提到的例子吗?多谢各位much@AbdelatifLatrach正如我allready所说的,geeric类型的参数(在括号内,要么是(MyType)result
,要么是DoSomething()`是编译时信息。但是,以字符串形式提供typename是一种运行时信息,这意味着在实际执行程序时对其进行计算。因此,简短的ANWR是:不,这是不可能的。
var result = (Enumerable) reflection.GetResultFromMethodInvoked("Person", "PersonRepository", "GetPersons");
foreach(var o in result) ...