我的问题
我遇到了一个无法解决问题的问题。我不想使用这么多代码,因为我有多个扩展另一个类的类(在我的例子中称为“数据”)。
我有一个日志文件,其中每个数据组都以特定的组名开头,例如“MitarbeiterSet”。抽象的数据类用于优先代码,我实现了像“String [] data”这样的变量(对于从日志文件解析的数据,例如< 101 4 3 6 3 30 80 2 0 0 1 300>)或“static String parseInduction”,用于确定此类是否是从中创建对象的正确类。
我有另一个名为ParseMonitor的类,它创建StreamReader来解析日志文件。因此,如果找到了正确的类,我将从右类引入setDataArray(StreamReader sr)函数,以解析数据数组。 (此时我必须告诉你,我需要那些不同的类,因为我需要特别将它们上传到sql服务器。)
这个静态函数创建了一个self对象,并使用 parseLine(String line)函数用给定行中的数据填充对象。
我需要什么。
我想通过拥有这个类的名称来调用任何类的静态函数。所以我不必使用那么多代码,并能够添加更多的类。
稍后我想调用每个类并使用 uploadToServer()将其上传到服务器。
这可能吗?
答案 0 :(得分:1)
我想调用任何类的静态函数,只需要具有该类的名称。
好吧,您可以使用Type.GetType(className)
来获取Type
(请注意,该名称至少需要完全限定,包括命名空间,并且根据您的具体情况,可能还需要程序集名称) ,然后Type.GetMethod
获得MethodInfo
。最后,调用MethodBase.Invoke
来调用方法。
如果您可以使用typeof(Foo)
而不是使用字符串,则可以使代码更简单,更健壮。
(旁注:如果您的方法真的被称为parseLine
,parseInduction
,setDataArray
等,您应该考虑将它们重命名为遵循.NET命名约定:)
答案 1 :(得分:1)
由于你的静态方法无论如何都在创建一个类的实例,我建议采用不同的方法:
创建一个包含ParseLine
的所有类都可以实现的接口。 (更改正确的返回类型):
public interface IParseLine
{
string ParseLine(string line);
}
让所有包含ParseLine()
的类实现IParseLine
。
创建类的实例,将其强制转换为IParseLine
,然后执行方法:
IParseLine pl = Activator.CreateInstance(Type.GetType(className)) as IParseLine;
if (pl != null)
{
string parsedString = pl.ParseLine(line);
// ...
}
修改来自评论:
我想创建一个while循环,可以如下所示: while {!sr.EndofStream){line = sr.ReadLine(); for(int i = 0; i< classNames.length; i ++){if(line.Contains(classNames [i] .MYINDICATOR){ CALL classNames [i]按以下方法划分的静态方法 创建数据类的对象}}
我没有对此进行测试,但您可以将代码更改为类似的内容(缓存获取MYINDICATOR
所需的反射):
IList<KeyValuePair<string, Type>> typeIndicators = classNames.Select(x => {
Type t = Type.GetType(x);
string indicator = (string)t.GetField("MYINDICATOR", BindingFlags.Public | BindingFlags.Static).GetValue(null);
return new KeyValuePair(indicator, t);
});
while (!sr.EndOfStream)
{
line = sr.ReadLine();
foreach (var types in typeIndicators)
{
if (line.Contains(types.Key))
{
IParseLine pl = Activator.CreateInstance(types.Value) as IParseLine;
if (pl != null)
{
string parsedString = pl.ParseLine(line);
}
}
}
}
答案 2 :(得分:1)
我想我知道你来自哪里。在下面这个简单的例子中,我有一个带有方法的静态类(没什么了不起的。)
public static class MyStaticClass
{
public static DateTime GetTime()
{
return DateTime.Now;
}
}
如果我想使用反射调用该方法,我可以使用以下代码,但它确实假设 MyStaticClass 类可通过引用或同一项目等获得。
MethodInfo method = typeof(MyStaticClass).GetMethod("GetTime");
object result = method.Invoke(null, null);
if (result is DateTime)
{
Console.WriteLine(((DateTime)result).ToLongTimeString());
}
当你没有引用课程时,你似乎要求的是这样做的一个方法。在这种情况下,尝试这样的事情:
MethodInfo method = Type.GetType("PocStaticReflect.MyStaticClass, PocStaticReflect, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null").GetMethod("GetTime");
object result = method.Invoke(null, null);
if (result is DateTime)
{
Console.WriteLine(((DateTime)result).ToLongTimeString());
}
注意完全限定的类名!
如果你正常工作,那么你可以简单地循环你的类名并调用你想要的方法。显然,你可能想要更多的错误检查以及 GetMethod()调用中的更多细节,但是这个shlud给你的要点。在将文件夹中的程序集循环到应用程序的拾取插件之前,我已经做了类似的事情。那个时候,每个类都实现了一个界面,使它们更容易定位,这可能是有用的路径。
答案 3 :(得分:1)
或试试这个:
private static object GetResultFromStaticMethodClass(string qualifiedClassName, string method)
{
Type StaticClass = Type.GetType(qualifiedClassName);
MethodInfo methodInfo = StaticClass.GetMethod(method);
object result = methodInfo.Invoke(null, null);
return result;
}
使用:
object result = GetResultFromStaticMethodClass(
"Utilities.StringHelper,DaProject",
"ToList"
);
在实用程序类中,在实用程序命名空间中,在 DaProject 中调用 StringHelper 类中的静态方法 ToList 项目(相同的程序集和项目名称)。
如果您需要参数,请将它们添加到 methodInfo.Invoke(null,null)调用中的第二个参数