1
votes

Passer ValueTuple au lieu d'arguments

Est-il possible de faire de cette manière (ou peut-être ai-je besoin d'une version spécifique de C #)?

public void DoWrite(string s1, string s2)
{
Console.WriteLine(s1+s2);
}
public (string,string) GetTuple()
{
//return some of them
}
//few lines later
DoWrite(GetTuple());

Mise à jour: je veux dire passer un tuple au lieu d'arguments séparés.

Function<int,int,int,int> triSum = (a,b,c) => {return a+b+c;};
var tup = (1,2,3);
triSum(tup); //passing one tuple instead of multiple args


6 commentaires

La réponse courte est non, cela n'est pas intégré à C #.


Merci, c'est ce que j'ai demandé.


Les réponses ici, et le doublon, reposent toutes sur la modification de la signature du délégué pour qu'elle corresponde davantage à ce que vous voulez accomplir, mais le déballage du paramètre * xxx que vous trouveriez dans Python n'existe pas dans C #.


Cependant, vous pourriez , bien que je ne le recommande pas, utiliser cette approche: triSum.DynamicInvoke (Enumerable.Range (0, tup.Length) .Select (i => tup [i] ) .ToArray ()); Ceci n'est disponible que dans .NET Core 2.x + je pense, pas dans .NET Framework.


Un peu moche, n'est-ce pas?


Oh, vraiment moche, comme je l'ai dit, je ne le recommanderais pas :)


3 Réponses :


0
votes

Il y a quelques erreurs dans le code, en bref les travaux suivants:

Func<Tuple<int,int,int>,int > triSum = a => { return a.Item1 + a.Item2 + a.Item3; };
Tuple<int,int,int> tup = new Tuple<int, int, int>(3,4,5);
triSum(tup); //passing one tuple instead of multiple args

Problèmes dans le code ci-dessus:

  1. Action est un délégué de fonction qui renvoie void , vous devez donc utiliser Func
  2. La façon dont vous avez passé les paramètres à Action en fait trois entiers indépendants et non un tuple
  3. De plus, la syntaxe var tup = (1,2) est à partir de c # 7.0 et ne peut pas être utilisée dans une version plus ancienne (un package nuget existe cependant)


3 commentaires

1. Merci, corrigé. 2. Et c'est une question principale - passer valuetuple dans des endroits qui attendent des arguments séparés. 3. Pas de problème. Je veux dire que j'ai peut-être besoin de C # 8 ou d'un package spécifique, etc. pour obtenir le comportement demandé?


@TrolltheLegacy Chaque tuple est un type différent, il n'est pas possible pour un compilateur de substituer un nombre d'entiers par un tuple ayant le même nombre d'entiers. Vous devrez modifier la définition de la fonction pour en faire explicitement un tuple


Et ça doit être une réponse.



4
votes

Oui, vous pouvez utiliser Named ValueTuples C # 7.1, ou même simplement une Méthode locale si cela convient à

void TriSum((int a, int b, int c) t)
   => Console.WriteLine(t.a + t.b + t.c);

TriSum((1, 2, 3));

ou simplement comme méthode locale

Action<(int a, int b, int c)> triSum = t 
   => Console.WriteLine(t.a + t.b + t.c);

triSum((1, 2, 3));


3 commentaires

J'aime aussi ta réponse. Mais pourquoi avez-vous changé Func en Action <(int, int, int)> ?


@Enigmativity Je crois que c'était une action à l'origine, ou peut-être que j'imaginais des choses


Oui tu as raison.



3
votes

Vous pouvez faire ceci:

Func<(int a, int b, int c), int> triSum = x => x.a + x.b + x.c;

Ou plus succinctement ceci:

Func<(int a, int b, int c), int> triSum = x => { return x.a + x.b + x.c; };

var tup = (1, 2, 3);

var sum = triSum(tup);


1 commentaires

Le vote favorable, car il est probablement plus conforme à ce que veut l'OP