実行時に指定された型に基づいて汎用型のアクションを作成できますか?この特定のシナリオでは、アクションの本体は最終的に引数タイプを無視します。型付きアクション<>は、引数のないアクションを囲むラッパーにすぎません。実行時に汎用型のアクション<>を作成する
Action original =() => { };
...
Action<TType> wrapper = (arg) => {
original();
}
か、さえ:
Action<TTypeA, TTypeB> wrapper = (arg) => {
original();
}
あなたが見ることができるように、入力されたアクション<>のボディは、それが単なるラッパーとして動作しています、引数、およびそのタイプを無視します。
なぜこのラッパーを最初に作成したいのか不思議であれば、「基本的な」バージョンは、Delegate.Combine()を実行するためにアクションをデリゲートに最終的に変換していることですタイプ。私がDelegate.Combine()で達成しようとしているのは、デリゲートが解雇されたという基本的な通知です。
この時点で、私はおそらく、これらのタイプの嫌悪感を避けるために私のデザインを再加工しますが、これがどのように達成されるのかはまだ非常に不思議です。
私が得ることができる最も近い従っていました:
private static TType GetTypedDelegate<TType>(Action onComplete)
where TType : class
{
MethodInfo info = typeof(TType).GetMethod("Invoke");
ParameterInfo[] parameters = info.GetParameters();
object result;
if (parameters.Length == 0)
result = onComplete;
else if (parameters.Length == 1)
result = GetTypedDelegate<TType>(onComplete, parameters[0].ParameterType);
// etc
TType onCompleteCasted = Delegate.CreateDelegate(typeof(TType), result, "Invoke") as TType;
return onCompleteCasted;
}
private static Delegate GetTypedDelegate<TType>(Action onComplete, Type type)
{
// This line isn't useful for me right now, since I can't just create a new
// instance of the action with a parameterless constructor ... but I thought I'd throw it in here in case it was of use
Type actionType = typeof(Action<>).MakeGenericType(new[] { type });
// Do some magic here with the type information
// The following of course does not work,but you get the idea of what I am aiming for
Action<type> wrapper = (arg1) =>
{
onComplete();
};
return wrapper as Delegate;
}
これはちょっとしたトリックです!今すぐ試してみてください。そのようなリターンの間に暗黙的な変換が起こることは私には起こりませんでした – Matt