[英]invoking a method with struct parameter using reflection in c#
我像這樣創建了一個 Class 庫項目
namespace ClassLibrary1
{
public class Class1
{
public string Method1(int x, string[] y)
{
if (x < 100)
{
return y[0];
}
else
{
return y[1];
}
}
}
}
然后,我創建了一個控制台應用程序項目並使用這樣的反射調用Method1
using System;
using System.Reflection;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<object> list = new List<object>();
list.Add(5);
string[] x = new string[2] { "N", "F" };
list.Add(x);
object output = null;
string DllFile = @"C:\Users\lenovo\source\repos\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll";
Assembly assembly = Assembly.LoadFrom(DllFile);
var types = assembly.GetTypes();
foreach (var j in types)
{
object l = j.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, null);
output = j.InvokeMember("Method1", BindingFlags.InvokeMethod, null, l, list.ToArray());
}
Console.WriteLine(output);
Console.ReadLine();
}
}
}
我成功地做到了。 現在,我正在嘗試調用Method1
,它使用反射將結構變量作為參數。 實際上,我正在嘗試在下面的代碼中調用Method1
namespace ClassLibrary1
{
public struct Person
{
public int personId;
public string firstName;
public string lastName;
}
public class Class1
{
public string Method1(int x, Person y)
{
if (x < 100)
{
return y.firstName;
}
else
{
return y.lastName;
}
}
}
}
我看到了一些樣品並嘗試了它們,但我失敗了。 我每次都得到一個例外
System.MissingMethodException: 'Method 'ClassLibrary1.Class1.Method1' not found.'
有人能幫我嗎? 這個異常有什么問題? 在我的第一次嘗試中,我沒有得到這樣的異常。
編輯:下面的代碼是我嘗試調用Method1
,它使用反射獲取結構變量作為參數
using System;
using System.Reflection;
using System.Collections.Generic;
namespace ConsoleApp1
{
public struct Person
{
public int personId;
public string firstName;
public string lastName;
}
class Program
{
static void Main(string[] args)
{
List<object> list = new List<object>();
list.Add(5);
Person x = new Person();
x.personId = 1;
x.firstName = "N";
x.lastName = "F";
list.Add(x);
object output = null;
string DllFile = @"C:\Users\lenovo\source\repos\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll";
Assembly assembly = Assembly.LoadFrom(DllFile);
var types = assembly.GetTypes();
foreach (var j in types)
{
object l = j.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, null);
output = j.InvokeMember("Method1", BindingFlags.InvokeMethod, null, l, list.ToArray());
}
Console.WriteLine(output);
Console.ReadLine();
}
}
}
為了
namespace ClassLibrary1
{
public struct Person
{
public int personId;
public string firstName;
public string lastName;
}
public class Class1
{
public string Method1(int x, Person y)
{
if (x < 100)
{
return y.firstName;
}
else
{
return y.lastName;
}
}
}
}
答案是
using System;
using System.Reflection;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
List<object> list = new List<object>();
list.Add(5);
string DllFile = @"C:\Users\lenovo\source\repos\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll";
Assembly assembly = Assembly.LoadFrom(DllFile);
var types = assembly.GetTypes();
foreach (var i in types)
{
if (i.Name == "Person")
{
var instance = Activator.CreateInstance(i);
var y = FillObject(instance);
list.Add(y);
}
}
object output = null;
foreach (var i in types)
{
if (i.Name == "Class1")
{
var methods = i.GetMethods();
foreach (var j in methods)
{
if (j.Name == "Method1")
{
output = j.Invoke(Activator.CreateInstance(i), list.ToArray());
}
}
}
}
Console.WriteLine(output);
Console.ReadLine();
}
static object FillObject(object o)
{
var type = o.GetType();
if (type.IsValueType)
{
var fields = type.GetFields();
foreach (var i in fields)
{
var fieldType = i.FieldType.Name;
if (fieldType == "Int32")
{
i.SetValue(o, 1);
}
if (fieldType == "String")
{
i.SetValue(o, "N");
}
}
}
return o;
}
}
}
嘗試這個:
class Program
{
static void Main(string[] args)
{
//var asy = Assembly.GetExecutingAssembly();
var asy = Assembly.LoadFrom(@"C:\Users\...\ClassLibrary1.dll");
// Get class reference
var t = asy.GetType("ConsoleApp1.Class1");
// Get method reference
var m1 = t.GetMethod("Method1", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
// create an instance of Class1
var ctor = t.GetConstructor(Type.EmptyTypes);
var obj = ctor.Invoke(null);
var intParam = 10;
var personParam = new Person() { firstName = "John", lastName = "Smith", personId = 100 };
var result = m1.Invoke(obj, new object[] { intParam, personParam }) as string;
Debug.WriteLine(result);
}
}
其中 class Method1
來自以下 class 定義
public class Class1
{
public string Method1(int x, Person y)
{
if (x < 100)
{
return y.firstName;
}
else
{
return y.lastName;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.