2009-02-25 4 views
3

Salut J'ai C# code similaire à ceci:C# out paramètres tricherie?

int someNumber; 
Thing someThing; 

doStuff(out someNumber); 
someThing = new Thing(someNumber); 

Ce que je voudrais savoir est s'il y a un moyen de supprimer la someNumber et instancier directement dans les QUELQUE CHOSE arguments de paramètres.

Modifier le code actaul me rend 8 paramètres out mais je juste essayer de garder les choses simples de sorte qu'il est plus comme:

int someNumber1, someNumber2, somNumber3, someNumber4, 
someNumber5, someNumber6, someNumber7, someNumber8; 

Thing someThing1, someThing2, someThing3, someThing4, 
someThing5, someThing6, someThing7, someThing8; 

doStuff(out someNumber1, out someNumber2, out someNumber3, out someNumber4, 
out someNumber5, out someNumber6, out someNumber7, out someNumber8); 

someThing1 = new Thing(someNumber1); etc..................... 

Répondre

1

Pas vraiment. Vous pouvez passer someThing en tant que byref, donc la méthode doStuff l'initialise, mais c'est méchant. Ce que vous avez ici est bien.

Vous devriez probablement retourner une valeur de doStuff, dans ce cas, c'est la meilleure approche:

var thing = new Thing(doStuff()); 

Out paramètres sont mieux utilisés lorsque vous souhaitez mettre en œuvre le modèle TryParse, ou lorsque vous devez retourner plusieurs valeurs d'un appel de fonction. Pour être honnête, même dans ce cas, il est préférable de renvoyer un objet avec des propriétés contenant les valeurs dont vous avez besoin.

0

Je ne pense pas que ce soit possible, étant donné que doStuff ne renvoie pas de valeur. Pourquoi veux-tu faire cela? IMHO mettre ces deux appels de fonction sur des lignes séparées est beaucoup plus lisible de toute façon, et même si c'était possible, il n'y aurait certainement pas d'augmentation de la performance.

3

Eh bien, tout d'abord, y at-il une raison pour laquelle vous ne pouvez pas utiliser un retour régulier au lieu de out ici? Ce serait plus propre (sauf s'il y a une bonne raison).

vous pouvez utiliser:

someThing = new Thing(doStuff()); 
+0

Non, il y a plusieurs paramètres et je n'ai pas écrit le code appelé et je ne veux pas l'envelopper. –

+0

Assez juste. Dans ce cas, je m'attends à ce que votre code actuel soit le plus propre possible (IMO). La chose de délégué est bien, mais se sent inutile ... –

5

Eh bien, si vous vous trouvez le faire régulièrement, vous pouvez faire quelque chose comme:

public delegate void OutAction<T>(out T value); 

public TResult UseOut<TIntermediate,TResult> 
    (OutAction<TIntermediate> outAction, 
    Func<TIntermediate,TResult> selector) 
{ 
    TIntermediate tmp; 
    outAction(out tmp); 
    return selector(tmp); 
} 

appeler ensuite avec (notez que doStuff ici est un groupe de méthodes - l'absence de() est délibérée!):

Thing someThing = UseOut(doStuff, x => new Thing(x)); 

Je ne dis pas nécessairement que c'est une bonne idée, juste quelque chose à considérer.

EDIT: Lorsque vous commencez à obtenir plusieurs paramètres, il devient beaucoup plus difficile - car le paramètre out pourrait être le premier, deuxième, troisième, quatrième, etc ...

EDIT: Version légèrement plus simple:

public TResult ReturnOut<TResult>(OutAction<TResult> outAction) 
{ 
    TResult tmp; 
    outAction(out tmp); 
    return tmp; 
} 

Utilisation:

Thing someThing = new Thing(ReturnOut(doStuff)); 
0

Si vous ne pouvez pas modifier la fonction appelée, et vous êtes peu disposé à l'envelopper, alors vous êtes coincé avec le code que vous avez.

Je suggère de l'emballer pour le nettoyer. Je l'aurais renvoyer un tableau int.

0

Dans cette situation particulière, vous pouvez non seulement revenir

List<Thing> 

avec le objectsz déjà instancié?

Je sais que cela ne répond pas à la question réelle, mais pourrait être utile dans ce scénario.

0

similaires à la réponse de ck, si toutes vos variables someNumber sont ints, vous pourriez avoir un retour DoStuff()List<int> ou IEnumerable<int>, puis itérer sur la liste retournée pour définir vos Thing objets. Si vos variables someNumber sont de types différents, vous pouvez créer un type de retour pour renvoyer la collection de valeurs. Cependant, si toutes ces valeurs ne sont que des paramètres constructeurs pour les objets Thing, je serais d'accord avec ck que vous devriez vraiment avoir DoStuff() retourner un List<Thing> ou IEnumerable<Thing>.