2015-08-23 2 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 не может тайному лямбда-выражения к объекту и во-вторых, объект не содержит определения для EmployeeID. Что мне не хватает?

+3

Если вам интересно, почему нет никакого ответа, даже не комментарий, ваш код очень трудно читать ... Как насчет упростить его и опубликовать только код, необходимый для воспроизведения проблемы? – Eser

+0

Работал над этим. Надеюсь получить ответы сейчас. Спасибо за указание @Eser – StrugglingCoder

+0

Какова цель этой переменной 'agrsDel'? Вы не используете его в коде. Вы также должны попробовать 'employeeType.GetMethod (« PromoteEmployees »). Invoke (...)' – thepirat000

ответ

1

он отлично работает теперь так вот полный код, я просто сделал 2 изменения -

1> список сотрудников был список объектов, поэтому он вызвал ошибку рассогласования, потому что PromoteEmployee ожидал список типов - Employee. Я изменил его, так что теперь это общий.

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

Я изменил свой код, чтобы использовать делегат. Создайте делегат. Это поможет?

 //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

Спасибо Абхинав и M4N. Но теперь, как передать этот делегат, вызывая PromoteEmployees() из этого класса через отражение. – StrugglingCoder

+0

Моя идея состояла в том, чтобы передать этот validaitonDelegate в функцию, подобную этой: dynamic value = employeeType.InvokeMember («PromoteEmployees», BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, employeeInstance, new Object [] {null, validationDelegate}); Но на данный момент у работодателя есть проблема с несоответствием типа ... поэтому я передал null и подтвердил свою идею. Он работает – Kapoor

+0

Эй! Я сделал 2 небольших изменения в yr-коде, который теперь работает. Я надеюсь, что это помогает. – Kapoor

Смежные вопросы