0

値を返すタスクがありますが、その値を別のものに変換したいと考えています (たとえば、 からstringint)。これは通常、非常に簡単に行うことができます。変換を行い、次のように新しい型を返す継続タスクを追加するだけです。

ConverterService converter = ...;
Task<string> originalTask = Task.Factory.FromAsync<string>(...);
Task<int> conversionTask = originalTask.ContinueWith(p => converter.Convert(typeof(string), typeof(int), p.Result));

問題は、タイプが不明であることです:(私はoriginalTask​​を動的に生成することができました。これは私の頭のてっぺんからの抜粋です:

ConverterService converter = ...;
// dynamically calling Task.Factory.FromAsync
var originalTask = FromAsyncMethodInfo.Invoke(Task.Factory, args.ToArray());
...

// now I want to dynamically call Task<string>.ContinueWith
var conversionTask = ContinueWithMethodInfo.Invoke(originalTask, ???)

私は今何をしますか?Func<Task<T>, U>(この例では実際に) を指定することを期待してFunc<Task<string>, int>いますが、これを動的に生成するにはどうすればよいでしょうか?

物事を単純にするために、変数Func<T>しかないときに実行時に動的に を作成する方法を知りたいだけです。Typeそれか、コードの最初のブロックに見られるラムダの動的に生成された代替のいずれか:

Task<int> conversionTask = originalTask.ContinueWith(p => converter.Convert(typeof(string), typeof(int), p.Result));

よろしくお願いします。

4

4 に答える 4

2

Task<object>アイテムをとして使用して渡すことができますobject。を使用してオブジェクトのタイプをフェッチできますobject.GetType()。次に例を示します。

void Main()
{
    var conversion = new ConversionService();
    var wantedType = typeof(string);

    Task<object> originalTask = Task<object>.Factory.StartNew(
       () => { /* test impl */ return 1; }); 

    var nextTask = originalTask.ContinueWith(prev =>
       conversion.ConvertObject(prev.Result.GetType(), wantedType, prev.Result));

    var result = nextTask.Result;
    Console.WriteLine("{0} - {1}", result.GetType(), result);
}

class ConversionService
{
    public object ConvertObject(Type source, Type dest, object input)
    {
        // test impl.
        return Convert.ChangeType(input, dest);
    }
}
于 2012-01-19T04:13:35.743 に答える
2

正確に何が必要かについて少し混乱していると思います...あなたが示すコードから、 Func は return を返すobject必要があり、タスクの実行後にオブジェクトのキャストを処理する必要があると思います。さらに進んで、 Func が戻り値の型を決定するロジックを含むものである場合、MyResultパラメーターReturnObjectおよびを持つ作成されたクラス を返すことができReturnType、実行後に をオブジェクトにキャストしReturnObjectますRetrunType

于 2012-01-19T00:13:57.210 に答える
0

私はそれを考え出した。私は最初に、期待するシグネチャを使用してメソッドを作成しました。

public TOutput HandleTask<TTaskInput, TOutput>(TTaskInput task)

このメソッドは、変換と例外処理を処理します。次に、Delegate.CreateDelegateを使用して、このメソッドへのデリゲートのインスタンスを作成します。次に、このインスタンスを動的なContinueWith呼び出しに渡します。

魅力のように実行されます。

于 2012-01-19T16:24:26.833 に答える
0

Func<TIn, TOut>変換を行うためのロジックを提供する必要があり、型がわかるまでロジックを提供できないため、動的に生成することはできません。

たとえば、int を文字列に変換する場合は ToString() を呼び出しますが、逆方向に変換する場合は int.TryParse() を使用します。可能な変換のセットが限られている場合は、既に構築されたデリゲートのコレクションでランタイム ルックアップに何らかのメカニズムを使用できますが、ある型の値を他の型に任意に変換できるコードを生成する方法はありません。

于 2012-01-19T00:28:22.960 に答える