2009-05-07 7 views
1

Supposons que vous avez une fonction qui renvoie un ENUM:Valeur à retourner pour indiquer la valeur invalide

public enum ServerStatus 
{ 
    Down, 
    Up 
} 

private ServerStatus GetServerStatus(int time) 
{ 
    if (time >= 0 && time < 12) 
    { 
     return ServerStatus.Down; 
    } 
    else if (time >= 12 && time <= 23) 
    { 
     return ServerStatus.Up; 
    } 
    else 
    { 
     return ?? // Server status is neither Up nor Down 
    } 
} 

Dois-je:

  1. Ajouter "Ni" à ServerStatus
  2. fait GetServerStatus retour ServerStatus? et return null
  3. Retour un autre bool qui indique si la valeur est significative
+1

En aparté, je serais probablement renomme « temps » à « heure », « HourOfDay », ou quelque chose –

+0

Je suis d'accord. Mais c'est un faux exemple de jouet que j'ai pensé juste pour illustrer mon propos. –

Répondre

13

Si ce cas ne devrait jamais se produire dans la pratique, et vous ne vous attendez pas à avoir à produire autre chose que « Up » et ' Down ', alors vous devriez jeter une exception.

+2

ArgumentOutOfRangeException, probablement; +1 –

+0

La condition ne devrait jamais arriver: si une exception est levée, je vais quand même avoir besoin de retourner une valeur valide, non? –

+1

Non; il n'y a pas de valeur de retour si vous lancez une exception. –

2

Si vous ne souhaitez pas lancer une exception, vous pouvez toujours avoir une valeur enum Unknown. Par exemple, l'état du serveur peut être Up, Down ou Unknown. Le statut inconnu peut être valide dans certains cas (par exemple si vous ne pouvez pas obtenir une connexion au serveur). Cette valeur inconnue pourrait être testée comme une valeur booléenne pour décider si la réponse est significative, le cas échéant. Je ne dis pas que c'est mieux qu'une ArgumentOutOfRangeException, mais c'est une autre façon de gérer le problème. Votre code d'appel pourrait toujours jeter l'exception en fonction d'autres critères.

2
private ServerStatus GetSeverStatus(int time) 
{ 
    if (time >= 0 && time < 12) 
    { 
     return ServerStatus.Down; 
    } 

    if (time >= 12 && time <= 23) 
    { 
     return ServerStatus.Up; 
    } 

    throw new ArgumentOutOfRangeException(); 
} 
0

Ma pensée serait le long de ces lignes:

Si c'est un cas exceptionnel (1 à 10 000 appels par an, une fois?) Ou une erreur irrécupérable soulever une exception.

Si le cas "inconnu" n'est pas exceptionnel ou s'il s'agit d'une erreur récupérable, j'irais avec une valeur "inconnue". La question devient alors vous ajoutez une troisième valeur ou allez avec un type nullable?

S'il est très probable, ajoutez un troisième état "inconnu" ou "impossible à obtenir".

Si ce n'est pas très probable, alors choisissez le type nullable.

Quelle que soit la solution que vous utilisiez, vous pourriez avoir besoin de savoir exactement pourquoi vous ne pouviez pas déterminer l'état du serveur - il n'y a peut-être pas de connexion, les identifiants peuvent être invalides, pour déterminer s'il faut réessayer immédiatement, réessayez après un certain délai ou simplement abandonner.

1

Voici un exemple de "comment appliquer mes conditions préalables à la fonction". Vous avez plusieurs façons de le faire. Une manière que j'apprécie vraiment est: avoir une fonction très simple «programmée par contrat» qui gère la pure logique métier: affirmer une condition préalable valide. Construire une fonction "sûre" en plus de cela, qui assure l'entrée est valide. Une autre approche, peut-être meilleure, consisterait à remplacer le type d'argument de fonction fourni par quelque chose qui ne peut pas être faux.

class ServerTime { 
    public ServerTime(uint hours) { seconds = (hours%24)*3600; } 
    private uint seconds; 
} 

public ServerStatus GetServerStatus(ServerTime time) { 
... 
} 
Questions connexes