Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在c中使用反射调用具有struct参数的方法#_C#_Reflection - Fatal编程技术网

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;
        }
    }
}