Создать делегат универсальной функции - PullRequest
3 голосов
/ 29 октября 2009

Я пишу несколько юнит-тестов, и у меня много функций вида

public void SomeTestHelperMethod<TKey, TValue>(TKey key, TValue value)

, который я неоднократно называю с различными аргументами, подобными этому

SomeTestHelperMethod<int, int>(0, 1);
SomeTestHelperMethod<int, object>(1, new Nullable<double>(16.5));
SomeTestHelperMethod<int, string>(2, "The quick brown fox jumped over the lazy dog.");
SomeTestHelperMethod<object, int>(new NullReferenceException(), 15);
SomeTestHelperMethod<object, object>(StringComparison.Ordinal, new Version());
SomeTestHelperMethod<object, string>((ushort)3, string.Empty);
SomeTestHelperMethod<string, int>(string.Empty, 195);
SomeTestHelperMethod<string, object>("A string", this);
SomeTestHelperMethod<string, string>("Another string", "Another string");

Я хотел бы написать функцию, которая принимает делегат Action и может вызывать делегат со всеми различными аргументами. Есть ли способ сделать это?

Ответ:

Благодаря MichaelCG вот что я в итоге сделал:

private void CallWithKeyAndValue(string methodName)
{
    MethodInfo method = typeof(ObservableDictionaryTest).GetMethod(methodName);
    foreach (KeyValuePair<object, object> kvp in ourKeyValueSet)
    {
        MethodInfo genericMethod = method.MakeGenericMethod(kvp.Key.GetType(), kvp.Value.GetType());
        genericMethod.Invoke(this, new[] { kvp.Key, kvp.Value });
    }
}

Я все еще заинтересован в более общем методе, но этот функционален для моих целей.

1 Ответ

6 голосов
/ 29 октября 2009

Если я вас правильно понимаю, это должно продемонстрировать, что вы пытаетесь сделать. Магия в MakeGenericMethod.

using System;

class Program {
    static void Main(string[] args) {
        var meth = typeof(Program).GetMethod("Meth");
        var items = new[] { 
            new { a = (object)"hi", b = (object)1 },
            new { a = (object)TimeSpan.MaxValue, b = (object)DateTime.UtcNow },
        };
        foreach (var item in items) {
            var gmeth = meth.MakeGenericMethod(item.a.GetType(), item.b.GetType());
            gmeth.Invoke(null, new[] { item.a, item.b });
        }
    }

    public static void Meth<A, B>(A a, B b) {
        Console.WriteLine("<{0}, {1}>", typeof(A).Name, typeof(B).Name);
    }
}

Выходы:

<String, Int32> 
<TimeSpan, DateTime>
...