2009-12-11 5 views
6

У меня есть метод следующей подпись:Проверка того, что `object [] args` удовлетворяет экземпляру делегата?

public static void InvokeInFuture(Delegate method, params object[] args) 
{ 
    // ... 
} 

Делегат и аргументы сохраняются в коллекцию для будущего призыва.

Есть ли способ проверить, удовлетворяет ли массив аргументов требованиям делегата без его вызова?

Спасибо.

EDIT: Спасибо за реализацию отражения, но я ищу встроенный способ сделать это. Я не хочу переустанавливать колесо, .NET Framework уже провела эту проверку, реализованную внутри Delegate.DynamicInvoke() где-то, реализацию, которая обрабатывает все эти сумасшедшие особые случаи, о которых могут подумать только разработчики Microsoft, и передала Unit Testing и QA. Есть ли способ использовать эту встроенную реализацию?

Спасибо.

ответ

6

Вы можете использовать отражение, чтобы получить подпись метода делегата следующим образом.

using System; 
using System.Reflection; 

bool ValidateDelegate(Delegate method, params object[] args) 
{ 
    ParameterInfo[] parameters = method.Method.GetParameters(); 
    if (parameters.Length != args.Length) { return false; } 

    for (int i = 0; i < parameters.Length; ++i) 
    { 
     if (parameters[i].ParameterType.IsValueType && args[i] == null || 
      !parameters[i].ParameterType.IsAssignableFrom(args[i].GetType())) 
     { 
      return false; 
     } 
    } 

    return true; 
} 
+0

Избили меня к нему, и у вас есть пример кода! +1 для полного ответа на его вопрос. –

+1

Ваш код не обрабатывает наследование, например аргумент типа FileStream является допустимым аргументом потока. Ваш код может работать, но факт заключается в том, что CLR может проверять себя внутри делегата. Invoke(). Есть ли способ повторного использования кода проверки CLR? Я хочу быть полностью совместимым с CLR. – DxCK

+1

Примечание: вы не должны проверять тип, подобный этому, поскольку это вернет false для экземпляров варианта (например, делегат, принимающий 'object', вернет false, если вы передадите' string' или что-то еще). Я предлагаю использовать 'parameters [i] .ParameterType.IsAssignableFrom (args [i] .GetType())' и дополнительно добавлять проверки для типа значения и 'null' (' args [i] .getType() 'будет терпеть неудачу если 'args [i]' is 'null'). – Lucero

1

кажется framework в основном делает выше, с некоторой элиминации логики, чтобы убедиться, что хранит список уже оцененных единиц.