通过以委托作为输入的反射调用方法

本文关键字:输入 反射 调用 方法 | 更新日期: 2023-09-27 18:09:16

在名称空间中定义了一个Employee class,代码片段如下

delegate  bool IsPromotable (Employee employee);
class Program
{
    public static void Main(string[] args)
    {
        List<Employee> empList = new List<Employee>();
        empList.Add(new Employee() { EmployeeId = 1, EmployeeName = "A", Salary = 7500, Experience = 2 });
        empList.Add(new Employee() { EmployeeId = 2, EmployeeName = "B", Salary = 11500, Experience = 6 });
        empList.Add(new Employee() { EmployeeId = 3, EmployeeName = "C", Salary = 14500, Experience = 5 });
        empList.Add(new Employee() { EmployeeId = 4, EmployeeName = "D", Salary = 10500, Experience = 7 });
        IsPromotable isPromotableObj = new IsPromotable(EnableToPromote);
        Employee EmployeeObj = new Employee();
        EmployeeObj.PromoteEmployees(empList, isPromotableObj);
    }
    public static bool EnableToPromote(Employee employee)
    {
        if (employee.Experience >= 5 && employee.Salary >= 10000)
        {
            return true;
        }
        else
            return false;
    }
}
class Employee
{
    public int EmployeeId { get; set; }
    public string EmployeeName { get; set; }
    public int Salary { get; set; }
    public int Experience { get; set; }
    public void PromoteEmployees(List<Employee> employeeList, IsPromotable isPromotableObj)
    {
        foreach (Employee employee in employeeList)
        {
            if (isPromotableObj(employee)) 
            {
                Console.WriteLine(" {0} will be promoted in the next R.P. Cycle ", employee.EmployeeName);
            }
        }
        Console.ReadKey();
    }
}

现在,通过反射从一个单独的命名空间中的一个单独的类中获得类类型和与之相关的所有其他类型对象。我还想调用PromoteEmployee()方法。我该怎么做?

Console.WriteLine("***************Loading External assembly*************");
Assembly assembly = Assembly.LoadFrom(@"C:'Users'Chiranjib'Documents'visual studio 2012'Projects'DelegatesSampleApplication'DelegatesSampleApplication'bin'Debug'DelegatesSampleApplication.exe");
Type employeeType = assembly.GetType("DelegatesSampleApplication.Employee"); //Gets the System.Type object for the Employee Class from the just loaded assembly with all it's dependencies
object employeeInstance = Activator.CreateInstance(employeeType);//Create an instance of the Employee Class Type
//sets it's properites
Console.WriteLine("***************Setting External assembly propeties for the second instance*************");
object employeeInstance2 = Activator.CreateInstance(employeeType);
//set's it's properties
Console.WriteLine("***************Creating an array list that will hold these employee instances***************");
List<Object> employeeInstanceList = new List<object>();
employeeInstanceList.Add(employeeInstance);
employeeInstanceList.Add(employeeInstance2);
Console.WriteLine("***************Invoking External assembly methods*************");
var agrsDel = new Object[] {(employeeInstance) => return employeeInstance};
dynamic value = employeeType.InvokeMember("PromoteEmployees", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, employeeInstance, new Object[] {employeeInstanceList,args})});
Console.ReadKey();

但是我得到的错误是agrsDel,它不能将lambda表达式转换为对象,其次对象不包含employeeId的定义。我错过了什么?

通过以委托作为输入的反射调用方法

它现在工作得很好,所以这里是完整的代码,我只做了2个更改-

1>的员工列表是一个对象列表,所以它产生了一个不匹配错误,因为PromoteEmployee期望一个类型为- Employee的列表。我改了,所以它现在是一个通用的。

2>我上面提到的建议,使用委托。CreateDelegate

    Console.WriteLine("***************Loading External assembly*************");
        Assembly assembly = Assembly.LoadFrom(@"CXXXXXX'ClassLibrary1'bin'Debug'ClassLibrary1.dll");
        Type employeeType = assembly.GetType("DelegatesSampleApplication.Employee"); //Gets the System.Type object for the Employee Class from the just loaded assembly with all it's dependencies
        object employeeInstance = Activator.CreateInstance(employeeType);//Create an instance of the Employee Class Type
        Console.WriteLine("***************Loading External assembly properties*************");
        PropertyInfo[] propertyInfoColl =  employeeType.GetProperties();
        foreach(var item in propertyInfoColl)
        {
            Console.WriteLine("Loaded Type Property Name {0} and default value {1}", item.Name, item.GetValue(employeeInstance, null));
        }
        Console.WriteLine("***************Setting External assembly propeties for the first instance*************");
        PropertyInfo employeeId = (PropertyInfo)employeeType.GetProperty("EmployeeId");
        employeeId.SetValue(employeeInstance, 1);
        Console.WriteLine("Employee Id Property value now set to " + employeeId.GetValue(employeeInstance,null));
        PropertyInfo employeeName = (PropertyInfo)employeeType.GetProperty("EmployeeName");
       employeeName.SetValue(employeeInstance, "A");
        Console.WriteLine("Employee Name Property value now set to " + employeeName.GetValue(employeeInstance, null));
        PropertyInfo salary = (PropertyInfo)employeeType.GetProperty("Salary");
        salary.SetValue(employeeInstance, 40000);
        Console.WriteLine("Salary Property value now set to " + salary.GetValue(employeeInstance, null));
        PropertyInfo experience = (PropertyInfo)employeeType.GetProperty("Experience");           
        experience.SetValue(employeeInstance, 3);
        Console.WriteLine("Experience Property value now set to " + experience.GetValue(employeeInstance, null));
        Console.WriteLine("***************Setting External assembly propeties for the second instance*************");
        object employeeInstance2 = Activator.CreateInstance(employeeType);
        PropertyInfo employeeId2 = (PropertyInfo)employeeType.GetProperty("EmployeeId");
        employeeId2.SetValue(employeeInstance2, 2);
        Console.WriteLine("Employee Id Property value now set to " + employeeId2.GetValue(employeeInstance2, null));
        PropertyInfo employeeName2 = (PropertyInfo)employeeType.GetProperty("EmployeeName");
        employeeName2.SetValue(employeeInstance2, "B");
        Console.WriteLine("Employee Name Property value now set to " + employeeName2.GetValue(employeeInstance2, null));
        PropertyInfo salary2 = (PropertyInfo)employeeType.GetProperty("Salary");
        salary2.SetValue(employeeInstance2, 50000);
        Console.WriteLine("Salary Property value now set to " + salary2.GetValue(employeeInstance2, null));
        PropertyInfo experience2 = (PropertyInfo)employeeType.GetProperty("Experience");
        experience2.SetValue(employeeInstance2, 6);
        Console.WriteLine("Experience Property value now set to " + experience2.GetValue(employeeInstance2, null));
        Console.WriteLine("***************Creating an array list that will hold these employee instances***************");
        /// list creation goes here 
        var listType = typeof(List<>);
        var constructedListType = listType.MakeGenericType(employeeType);
        var employeeInstanceListType = Activator.CreateInstance(constructedListType);
        var employeeInstanceListInstance = (IList)Activator.CreateInstance(constructedListType);
        employeeInstanceListInstance.Add(employeeInstance);
        employeeInstanceListInstance.Add(employeeInstance2);
        Console.WriteLine("***************Invoking External assembly methods*************");
        //var agrsDel = new Object[] {(employeeInstance) => return employeeInstance};         
        Delegate validationDelegate;
        try
        {
            Type prog = assembly.GetType("DelegatesSampleApplication.Program");
            Type delegateType = assembly.GetType("DelegatesSampleApplication.IsPromotable");
            // Convert the Arg1 argument to a method
            MethodInfo mi = prog.GetMethod("EnableToPromote",
            BindingFlags.Public | BindingFlags.Static);
            // Create a delegate object that wraps the static method
            validationDelegate = Delegate.CreateDelegate(delegateType, mi);
        }
        catch (ArgumentException)
        {
            Console.WriteLine("Phew... not working" );
            return;
        }

        dynamic value = employeeType.InvokeMember("PromoteEmployees", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, employeeInstance, new Object[] { employeeInstanceListInstance, validationDelegate });

我改变了你的代码使用委托。创建委托。这对你有帮助吗?

        //var agrsDel = new Object[] {(employeeInstance) => return employeeInstance};         
        Delegate validationDelegate;
        try
        {
            Type prog = assembly.GetType("DelegatesSampleApplication.Program");
            Type delegateType = assembly.GetType("DelegatesSampleApplication.IsPromotable");
            // Convert the Arg1 argument to a method
            MethodInfo mi = prog.GetMethod("EnableToPromote",
            BindingFlags.Public | BindingFlags.Static);
            // Create a delegate object that wraps the static method
            validationDelegate = Delegate.CreateDelegate(delegateType, mi);
        }
        catch (ArgumentException)
        {
            Console.WriteLine("Phew... not working" );
            return;
        }