C# 在c中使用反射调用具有struct参数的方法#
我创建了一个类库项目,如下所示C# 在c中使用反射调用具有struct参数的方法#,c#,reflection,C#,Reflection,我创建了一个类库项目,如下所示 namespace ClassLibrary1 { public class Class1 { public string Method1(int x, string[] y) { if (x < 100) { return y[0]; } else {
namespace ClassLibrary1
{
public class Class1
{
public string Method1(int x, string[] y)
{
if (x < 100)
{
return y[0];
}
else
{
return y[1];
}
}
}
}
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;
}
}
}
}
有人能帮我吗?这个异常有什么问题?在我的第一次尝试中,我没有得到这样的例外
编辑:
下面的代码是我调用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();
}
}
}
使用系统;
运用系统反思;
使用System.Collections.Generic;
名称空间控制台EAPP1
{
公共结构人
{
公共国际人格;
公共字符串名;
公共字符串lastName;
}
班级计划
{
静态void Main(字符串[]参数)
{
列表=新列表();
增加(5);
人员x=新人员();
x、 personId=1;
x、 firstName=“N”;
x、 lastName=“F”;
增加(x);
对象输出=null;
字符串DllFile=@“C:\Users\lenovo\source\repos\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll”;
Assembly=Assembly.LoadFrom(DllFile);
var types=assembly.GetTypes();
foreach(类型中的var j)
{
对象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.ReadLine();
}
}
}
试试这个:
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);
}
}
以下类别定义中的哪个类别Method1
public class Class1
{
public string Method1(int x, Person y)
{
if (x < 100)
{
return y.firstName;
}
else
{
return y.lastName;
}
}
}
公共类1
{
公共字符串方法1(整数x,人y)
{
如果(x<100)
{
返回y.firstName;
}
其他的
{
返回y.lastName;
}
}
}
用于
命名空间类库1
{
公共结构人
{
公共国际人格;
公共字符串名;
公共字符串lastName;
}
公共班级1
{
公共字符串方法1(整数x,人y)
{
如果(x<100)
{
返回y.firstName;
}
其他的
{
返回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;
}
}
}
使用系统;
运用系统反思;
使用System.Collections.Generic;
名称空间控制台EAPP1
{
班级计划
{
静态void Main(字符串[]参数)
{
列表=新列表();
增加(5);
字符串DllFile=@“C:\Users\lenovo\source\repos\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll”;
Assembly=Assembly.LoadFrom(DllFile);
var types=assembly.GetTypes();
foreach(类型中的变量i)
{
如果(即姓名=“人”)
{
var instance=Activator.CreateInstance(i);
var y=FillObject(实例);
列表。添加(y);
}
}
对象输出=null;
foreach(类型中的变量i)
{
如果(i.Name==“Class1”)
{
var methods=i.GetMethods();
foreach(方法中的var j)
{
如果(j.Name==“Method1”)
{
output=j.Invoke(Activator.CreateInstance(i),list.ToArray());
}
}
}
}
控制台写入线(输出);
Console.ReadLine();
}
静态对象FillObject(对象o)
{
var type=o.GetType();
if(type.IsValueType)
{
var fields=type.GetFields();
foreach(字段中的变量i)
{
var fieldType=i.fieldType.Name;
如果(fieldType==“Int32”)
{
i、 设定值(o,1);
}
如果(字段类型==“字符串”)
{
i、 设定值(o,“N”);
}
}
}
返回o;
}
}
}
在我们继续之前-您了解什么是output=j.InvokeMember(“Method1”,BindingFlags.InvokeMethod,null,l,list.ToArray())
正在做什么?您也正在对类库中的所有类型调用Method1
。这似乎有些古怪,因为编译器可能会在代码之外生成一些支持类型(请参见闭包)。为什么不在创建实例之前找到特定的类型Class1
。可以对该方法进行重载。所以要小心,原来的代码将y作为数组,而新代码将y作为单例。因此,请确保您的代码已重新编译。
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;
}
}
}