在名称空间中定义了一个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:UsersChiranjibDocumentsvisual studio 2012ProjectsDelegatesSampleApplicationDelegatesSampleApplicationbinDebugDelegatesSampleApplication.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(@"CXXXXXXClassLibrary1binDebugClassLibrary1.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;
}