2015-08-23 25 views
0

我有一个命名空间中定义一个Employee类和代码段经由反射是这样调用通过反射接受一个代表作为输入

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表达式的一个对象,其次对象不包含对雇员的定义。我错过了什么?

+3

如果你想知道为什么没有任何反应,甚至没有评论,你的代码是非常难读......怎么样简化它并只发布重现问题所需的代码? – Eser

+0

就此工作。现在希望得到回应。感谢您指出@Eser – StrugglingCoder

+0

'agrsDel'变量的用途是什么?你没有在代码中使用它。你也应该尝试'employeeType.GetMethod(“PromoteEmployees”)。调用(...)' – thepirat000

回答

1

现在的工作细所以这里是完整的代码,我只是做了2个变化 -

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

2>我上面提到的,建议使用Delegate.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 }); 
1

我改变了你的代码来使用Delegate.Create委托。这对你有帮助吗?

 //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; 
     } 
+0

感谢Abhinav和M4N。但是现在,如何通过反射从此类调用PromoteEmployees()时传递此委托。 – StrugglingCoder

+0

我的想法是通过这个validaitonDelegate到像这样的函数 - dynamic value = employeeType.InvokeMember(“PromoteEmployees”,BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,null,employeeInstance,new Object [] {null, validationDelegate}); 但目前雇员列表有一些类型不匹配问题...所以我通过了一个空&验证我的想法。它的工作原理 – Kapoor

+0

嘿!我现在对年代码做了2个小改动。我希望它有帮助。 – Kapoor