通过classname调用静态函数作为c#中的字符串

时间:2012-08-21 17:12:56

标签: c# string function reflection static

我的问题

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

我有一个日志文件,其中每个数据组都以特定的组名开头,例如“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()将其上传到服务器。

这可能吗?

4 个答案:

答案 0 :(得分:1)

  

我想调用任何类的静态函数,只需要具有该类的名称。

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

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

(旁注:如果您的方法真的被称为parseLineparseInductionsetDataArray等,您应该考虑将它们重命名为遵循.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)调用中的第二个参数