0

私の問題

自分では解決できない問題があります。別のクラスを拡張する複数のクラスがあるため、あまり多くのコードを使用したくありません(私の場合は「データ」と呼ばれます)。

ログ ファイルがあり、各データ グループは特定のグループ名 ("MitarbeiterSet" など) で始まります。抽象データクラスは、多くのコードを優先するために使用され、「String[] data」のような変数を実装しました (ログファイルから解析されたデータ用、例: < 101 4 3 6 3 30 80 2 0 0 1 300 >)または"static String parseInduction"。これは、このクラスがオブジェクトを作成するのに適しているかどうかを判断するために使用されます。

ログ ファイルを解析する StreamReader を作成する ParseMonitor という別のクラスがあります。したがって、適切なクラスが見つかった場合は、適切なクラスから setDataArray(StreamReader sr) 関数を導入して、データ配列を解析します。(この時点で、これらの異なるクラスが必要であることをお伝えしなければなりません。具体的には、それらを SQL サーバーにアップロードする必要があるためです。)

この静的関数は、それ自体のオブジェクトを作成し、parseLine(String line)関数を使用して、指定された行からのデータでオブジェクトを埋めます。

私が必要とするもの。

このクラスの名前を持つだけで、任意のクラスの静的関数を呼び出したいです。そのため、それほど多くのコードを使用する必要はなく、さらにクラスを追加できます。

後で、すべてのクラスを呼び出し、uploadToServer()を使用してサーバーにアップロードしたいと考えています。

これは可能ですか?

4

4 に答える 4

1

このクラスの名前を付けるだけで、任意のクラスの静的関数を呼び出したい。

を使用Type.GetType(className)してType(名前は名前空間を含めて少なくとも完全に修飾されている必要があり、正確なシナリオによってはアセンブリ名も必要になる場合があることに注意してください)、次にType.GetMethodを取得するために使用できMethodInfoます。最後に、MethodBase.Invokeを呼び出してメソッドを呼び出します。

typeof(Foo)文字列を使用する代わりに使用できる場合は、コードがより単純で堅牢になります。

(補足:メソッドが実際parseLineparseInductionsetDataArrayなどと呼ばれている場合は、.NETの命名規則に従うように名前を変更することを検討する必要があります:)

于 2012-08-21T17:16:57.020 に答える
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()呼び出しでより多くのエラー チェックと詳細が必要になる可能性がありますが、このシュラウドはその要点を示しています。フォルダー内のアセンブリをループしてアプリケーションのプラグインをピックアップする前に、同様のことを行いました。その時、各クラスは見つけやすくするためのインターフェースを実装しました。

于 2012-08-22T10:29:49.433 に答える
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 ループを作成したいと考えています。for(int i = 0; i < classNames.length; i++){ if(line.Contains(classNames[i].MYINDICATOR){ CALL 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

またはこれを試してください:

 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)呼び出しの 2 番目のパラメータに追加します。

于 2013-04-11T06:44:31.780 に答える