我有一个关于c sharp反射的问题。这是我的问题
1)定义类MyClass
不同的字段,不同的访问器(private, public, protected),不同的方法,不同的参数集和返回类型
2)定义包含以下方法的MyTestClass
:为指定的类名打印方法名,其中方法包含字符串参数,类名为字符串值。调用类的某个方法,并将参数放入方法,参数应该从文本文件中读取(类名和方法名是方法的参数
我想调用method5在我的类,但它需要两个参数,当我试图我得到一个不匹配计数参数错误,我怎么能传递两个参数int
和double
,使调用方法工作?
Inside params.txt there is
10 1.5
和我想从一个文本文件中读取,这是我的完整代码下面有任何想法或修改我将感激
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
class MyClass
{
private int i;
public double d;
private string s;
public bool b;
public MyClass()
{
i = 1;
d = 0.1;
s = "1";
b = true;
}
public void Method0()
{
Console.WriteLine("Method with no arguments, no return value.");
}
private int Method1(int arg0)
{
Console.WriteLine("The method returns int, int gets.");
return arg0;
}
private double Method2(int arg0, double arg1)
{
Console.WriteLine("Method returns a double, taking int and double.");
return arg1 * arg0;
}
public bool Method3(string arg0)
{
Console.WriteLine("Method returns a bool, accepts string");
return arg0.Length>10;
}
public bool Method3(string arg0,string arg1)
{
Console.WriteLine("The method takes two arguments string.");
return arg0 == arg1;
}
public static char Method4(string arg0)
{
Console.WriteLine("Method returns a char, accepts string. .");
Console.WriteLine(arg0);
return arg0[1];
}
public void Method5(int arg0, double arg1)
{
Console.WriteLine("arg1 = {0} arg2 = {1}.",arg0,arg1);
}
}
class MyTestClass
{
public static string[] GetMethodsWithStrParams(string className)
{
var t = Type.GetType(className);
List<string> res = new List<string>();
foreach (var method in t.GetMethods())
{
foreach (var param in method.GetParameters())
{
if (param.ParameterType == typeof(string))
{
res.Add(method.Name);
break;
}
}
}
return res.ToArray();
}
public static void InvokeMethod(string className, string methodName, string fileName)
{
var t = Type.GetType(className);
using (StreamReader f = new StreamReader("params.txt"))
{
t.GetMethod(methodName).Invoke(t.GetConstructor(Type.EmptyTypes).Invoke(new object[] { }),
new object[] { f.ReadLine(), f.ReadLine()+"1" });
}
}
}
class Program
{
static void Main(string[] args)
{
string name = "MyClass";
foreach (var x in MyTestClass.GetMethodsWithStrParams(name))
{
Console.WriteLine(x);
}
MyTestClass.InvokeMethod("MyClass", "Method5", "params.txt");
Console.ReadKey(true);
}
}
您需要将文件中的所有字符串转换为方法中使用的各自类型:
using System;
using System.Linq;
using System.IO;
class MyInvokedClass
{
public void MyInvokedMethod(int arg0, double arg1)
{
Console.WriteLine("arg1 = {0} arg2 = {1}.", arg0, arg1);
}
}
class Program
{
public static void InvokeMethod(string className, string methodName, string fileName)
{
string[] contents = File.ReadAllLines(fileName);
var t = Type.GetType(className);
var m = t.GetMethod(methodName);
var parametertypes = m.GetParameters().Select(p => p.ParameterType);
var parameters = parametertypes.Select((type, index) => Convert.ChangeType(contents[index], type)).ToArray();
var instance = Activator.CreateInstance(t);
m.Invoke(instance, parameters);
}
static void Main()
{
InvokeMethod("MyInvokedClass", "MyInvokedMethod", "params.txt");
Console.ReadKey(true);
}
}
文件如下:
42
12.34
(注意,您可能必须替换。
由于这是你上一个问题的延续,这里有几个问题需要你解决:
1)我不认为你想让params.txt只包含Method5
的参数,否则你的应用程序会失败,当你尝试另一种方法
2)您需要将file中的行解析为对象数组。
我会写
params.txt:
Method5: 1 1.5
Method4: some string
...
我建议使用制表符作为分隔符或管道(|)或任何你不期望在有效参数中使用的东西,否则你将无法拥有包含空格的字符串。
现在,您的代码需要找到要调用的方法的行,并将其分成几部分以获得参数。例如,对于method5
,你现在将有两个字符串表示参数:"1"one_answers"1.5"
接下来你要做的是将这些字符串转换为方法调用的正确类型的对象(即int和double)。
一种方法是将参数类型编码为params.txt:
Method5L: 1:int 1.5:float
,但是这很容易出错,当你改变你的方法时,它很容易不同步,所以更好的方法是通过反射获得参数类型,即从代表方法的MethodInfo
对象:
var parameters = method.GetParameters();
最后一步是进行转换-您可以使用int.Parse
, double.Parse
或更好的Convert
类方法,例如:Convert.ChangeType("1.5", typeof(float))
var args = new objects[parameters.Length];
var argStrings = {"1", "1.5"}; // obviously, you must get these from params.txt, not hardcode it
int idx = 0;
foreach (var param in parameters) {
args[idx] = Convert.ChangeType(argStrings[idx], param.ParameterType);
idx++;
}
现在你可以通过Invoke
提供args
数组作为参数列表给你的方法。
好了,现在你只需要对它进行编码