2009-10-05 8 views
9

Existe-t-il un moyen de décorer une méthode qui va faire de la journalisation, puis lancer une exception inconditionnellement, en tant que telle?Comment marquer une méthode lancera inconditionnellement?

J'ai le code comme ceci:

void foo(out int x) 
{ 
    if(condition()) { x = bar(); return; } 

    // notice that x is not yet set here, but compiler doesn't complain 

    throw new Exception("missed something."); 
} 

Si je l'ai essayer d'écrire comme cela, je reçois un problème:

void foo(out int x) 
{ 
    if(condition()) { x = bar(); return; } 

    // compiler complains about x not being set yet 

    MyMethodThatAlwaysThrowsAnException("missed something."); 
} 

Toutes les suggestions? Merci.

+0

Quel problème obtenez-vous? –

+0

"x a l'attribut out et n'a pas encore été défini à la fin de la méthode" – k0dek0mmand0

+1

Je suis confus - comment est-il lancé inconditionnellement s'il n'est pas lancé quand x est positionné (et un retour est fait) – Matt

Répondre

17

Que pensez-vous de cela?

bool condition() { return false; } 
int bar() { return 999; } 
void foo(out int x) 
{ 
    if (condition()) { x = bar(); return; } 
    // compiler complains about x not being set yet 
    throw MyMethodThatAlwaysThrowsAnException("missed something."); 
} 
Exception MyMethodThatAlwaysThrowsAnException(string message) 
{ 
    //this could also be a throw if you really want 
    // but if you throw here the stack trace will point here 
    return new Exception(message); 
} 
2

Si vous savez que l'exception sera toujours levée, pourquoi est-ce important? Il suffit de définir la variable à quelque chose il peut donc compiler:

void foo(out int x) 
{ 
    if(condition()) { x = bar(); return; } 

    x = 0; 

    MyMethodThatAlwaysThrowsAnException("missed something."); 
} 
+3

C'est exactement ce que je voulais éviter.:) – k0dek0mmand0

0

Il ne répond pas à votre question, mais lorsque vous utilisez des paramètres, il est toujours une bonne idée de les initialiser au début de la méthode. De cette façon, vous n'aurez pas des erreurs du compilateur:

void foo(out int x) 
{ 
    x = 0; 
    if(condition()) { x = bar(); return; } 
    MyMethodThatAlwaysThrowsAnException("missed something."); 
} 
+4

Je pense que les paramètres devraient être assignés là où cela a du sens ou parce qu'ils pourraient empêcher certains bogues cachés au moment de la compilation juste parce que vous avez oublié d'assigner un paramètre à un chemin de code. –

1

x est un paramètre sur et doit être réglé avant que vous aller de l'avant

+3

sauf si une exception est levée – k0dek0mmand0

+1

Il est toujours bon de s'assurer que tous les paramètres out sont définis au début de la méthode et leur attribuer des valeurs par défaut s'ils ne le sont pas. –

2

Il n'y a aucun moyen de marquer une méthode de cette façon.

Peut-être pas pertinent, mais le modèle dans votre exemple, utilisant un paramètre out, est un peu étrange. Pourquoi ne pas simplement avoir un type de retour sur la méthode à la place?

int Foo() 
{ 
    if (condition()) return bar(); 

    MyMethodThatAlwaysThrowsAnException("missed something."); 
} 
+0

C'était juste un exemple simple. Le code actuel est plutôt plus complexe. – k0dek0mmand0

+0

@ k0dek0mmand0: Je me doutais que cela pourrait être le cas. Je suppose que vous n'avez pas de chance - il n'y a aucun moyen de dire au compilateur que 'MyMethodThatAlwaysThrowsAnException' se lance toujours. – LukeH

1

Si vous ne voulez pas avoir à définir x, pourquoi n'utilisez-vous pas simplement un paramètre ref à la place?

void foo(ref int x) 
{ 
    if(condition()) { x = bar(); return; } 

    // nobody complains about anything 

    MyMethodThatAlwaysThrowsAnException("missed something."); 
} 
2

Il est un fil très vieux, mais je veux juste vous ajouter devriez écrire différent du début:

void foo(out int x) 
{ 
    if (!condition()) 
     MyMethodThatAlwaysThrowsAnException("missed something."); 

    x = bar(); 
    // and so on... 
} 

Ce compilateur moyen ne se plaindra pas et votre code est beaucoup plus clair.

+0

Le code réel est probablement plus complexe, de sorte que votre suggestion peut ne pas avoir de sens. –

Questions connexes