Могу ли я использовать параметры в действии или делегаты Func?

StackOverflow https://stackoverflow.com/questions/4059624

Вопрос

Когда я пытаюсь использовать параметры в делегате действий ...

private Action<string, params object[]> WriteToLogCallBack;

Я получил эту ошибку времени проекта:

Недопустимый токен «Парами» в классе, структуре или декларации участника интерфейса

Любая помощь!

Это было полезно?

Решение

Как насчет этого обходного пути?

private Action<string, object[]> writeToLogCallBack;
public void WriteToLogCallBack(string s, params object[] args)
{
  if(writeToLogCallBack!=null)
    writeToLogCallBack(s,args);
}

Или вы можете определить свой собственный тип делегата:

delegate void LogAction(string s, params object[] args);

Другие советы

Вариадические параметры типа невозможны в C #.

Вот почему много деклараций для Action<...>, Func<...>, а также Tuple<...>, Например. Это было бы интересной особенностью, хотя. C ++ 0x. имеет их.

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

public delegate T ParamsAction<T>(params object[] oArgs);

public static T LogAction<T>(string s, ParamsAction<T> oCallback)
{
    Log(s);
    T result = oCallback();
    return T;
}

Foo foo = LogAction<Foo>("Hello world.", aoArgs => GetFoo(1,"",'',1.1));

Вы можете использовать params В фактической декларации делегата, но не в типе одного. Общие параметры к действию являются только типы, а не фактические аргументы, которые будут переданы при вызове делегата. Пармы не являются типом, это ключевое слово.

Я сделал незначительное расширение вышеуказанному коду из Bryan, чтобы показать, как обернуть несколько вызовов метода.
Я использую это, чтобы обернуть несколько методов, которые содержат вызовы базы данных в одну транзакцию.
Спасибо Брайан :-)
(Вы можете запустить следующее в LinqPad для тестирования)

//Wrapper code
public delegate void MyAction(params object[] objArgs);
public static void RunActions(params MyAction[] actnArgs)
{
    Console.WriteLine("WrapperBefore: Begin transaction code\n");
    actnArgs.ToList().ForEach( actn =>  actn() );
    Console.WriteLine("\nWrapperAfter: Commit transaction code");
}

//Methods being called
public void Hash  (string s, int i, int j)  => Console.WriteLine("   Hash-method call: " + s + "###" + i.ToString() + j.ToString());
public void Slash (int i, string s)         => Console.WriteLine("   Slash-method call: " + i.ToString()+ @"////" + s);

//Actual calling code
void Main()
{  
  RunActions( objArgs => Hash("One", 2, 1)
             ,objArgs => Slash(3, "four")   );
}

//Resulting output: 
// 
//  WrapperBefore: Begin transaction code
//  
//  Hash-method call: One###21
//  Slash-method call: 3////four
//  
//  WrapperAfter: Commit transaction code  
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top