0

我的问题

我有一个我无法解决的问题。我不想使用这么多代码,因为我有多个扩展另一个类的类(在我的例子中它称为“数据”)。

我有一个日志文件,其中每个数据组都以特定的组名开头,例如“MitarbeiterSet”。抽象的 Data-Class 用于处理大量代码,其中我实现了诸如“String[] data”之类的变量(对于从日志文件中解析的数据,例如 < 101 4 3 6 3 30 80 2 0 0 1 300 >)或"static String parseInduction",用于确定该类是否适合从中创建对象。

我有另一个名为 ParseMonitor 的类,它创建 StreamReader 来解析日志文件。所以如果找到了正确的类,我从正确的类中引入 setDataArray(StreamReader sr) 函数来解析数据数组。(此时我必须告诉你,我需要那些不同的类,因为我需要专门将它们上传到 sql 服务器。)

这个静态函数创建一个它自己的对象,并使用parseLine(String line)函数用给定行的数据填充对象。

我需要的。

我想调用任何类的静态函数,只要有这个类的名字。所以我不必使用那么多代码并且能够添加更多类。

稍后我想调用每个类并使用uploadToServer()将其上传到服务器。

这可能吗?

4

4 回答 4

1

我想调用任何类的静态函数,只要有这个类的名字。

好吧,您可以使用Type.GetType(className)来获取 a Type(请注意,名称至少需要完全限定,包括命名空间,并且可能还需要程序集名称,具体取决于您的具体情况),然后Type.GetMethod获取MethodInfo. 最后,调用MethodBase.Invoke调用该方法。

如果您可以使用typeof(Foo)而不是使用字符串,它将使代码更简单、更健壮。

(旁注:如果您的方法真的被称为parseLine,parseInductionsetDataArray,您应该考虑重命名它们以遵循 .NET 命名约定 :)

于 2012-08-21T17:16:57.020 回答
1

由于您的静态方法无论如何都在创建其类的实例,因此我建议采用不同的方法:

创建一个所有包含的类都ParseLine可以实现的接口。(将返回类型更改为正确的类型):

public interface IParseLine
{
    string ParseLine(string line);
}

拥有所有包含ParseLine()implement的类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){ 调用 classNames[i] 静态方法来解析以下行并创建其类的数据对象} }

我没有对此进行测试,但您可以将代码更改为类似这样(缓存 get 所需的反射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);
             }
        }
    }
}
于 2012-08-21T18:04:39.030 回答
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 会为您提供它的要点。在遍历文件夹中的程序集以获取应用程序的插件之前,我已经做了类似的事情。那个时候,每个类都实现了一个接口,使它们更容易定位,这可能是一个有用的路径。

于 2012-08-22T10:29:49.433 回答
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项目(相同的程序集和项目名称)中的Utilities命名空间中的StringHelper类中的静态方法ToList 。

如果需要参数,请在methodInfo.Invoke(null, null)调用的第二个参数中添加它们

于 2013-04-11T06:44:31.780 回答