Question

Quand je tente d'utiliser params dans un délégué d'action ...

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

J'ai reçu cette erreur de temps de conception:

  

non valide jeton 'params' en classe, struct ou déclaration de membre d'interface

Toute aide!

Était-ce utile?

La solution

Que diriez-vous cette solution de contournement?

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

Ou vous pouvez définir votre propre type de délégué:

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

Autres conseils

paramètres de type VARIADIC ne sont pas possibles en C #.

Voilà pourquoi de nombreuses déclarations Il es pour Action<...>, Func<...> et Tuple<...>, par exemple. Ce serait une caractéristique intéressante, cependant. C ++ 0x les a .

Vous pouvez essayer cela. Il permet un certain nombre d'arguments, et vous obtiendrez une erreur de compilation si vous passez le mauvais numéro ou le type d'arguments.

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));

Vous pouvez utiliser params dans la déclaration réelle d'un délégué, mais pas dans le type d'un. Les paramètres génériques à une action sont des types, non seulement les arguments réels à transmettre lors de l'appel du délégué. params est pas un type, il est un mot-clé.

Je l'ai fait une extension mineure au code ci-dessus de Bryan, pour montrer comment emballer les appels de méthode multiples.
J'utilise ceci pour envelopper plusieurs méthodes qui contiennent des appels de base de données, en une seule transaction.
Merci Bryan :-)
(Vous pouvez exécuter ce qui suit dans LINQPad à tester)

//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  
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top