2010-05-02 3 views
2
public static string GetUa(HttpRequest hr) 
{ 
    try 
    { 
     string visitorBrowser = hr.UserAgent.ToString(); 
     string originalBrowser = hr.ServerVariables["X-OperaMini-Phone-UA"]; 
     string anotherOriginalBrowser = hr.ServerVariables["X-Device-User-Agent"]; //novarra 

     if (!String.IsNullOrEmpty(originalBrowser)) 
     { 
      return "OPERAMINI " + originalBrowser; 
     } 
     else 
     { 
      if (!String.IsNullOrEmpty(anotherOriginalBrowser)) 
      { 
       return "NOVARRA " + anotherOriginalBrowser; 
      } 
      else 
      { 
       return visitorBrowser; 
      } 
     } 
    } 
    catch 
    { 
     return "No UA Found"; 
    } 
} 
+2

appel à 'ToString()' 'sur hr.UserAgent' n'est pas nécessaire, car il est déjà chaîne et éliminera l'utilisation des exceptions dans le cadre de votre flux de méthode. – statenjason

+0

Merci, je ne savais pas que – nLL

Répondre

9

Je serais plus préoccupé par la lisibilité. Cela me semble plus agréable à:

var operaAgent = hr.ServerVariables["X-OperaMini-Phone-UA"]; 
var deviceAgent = hr.ServerVariables["X-Device-User-Agent"]; 

operaAgent = string.IsNullOrEmpty(operaAgent) ? null : "OPERAMINI" + operaAgent; 
deviceAgent = string.IsNullOrEmpty(deviceAgent) ? null : "NOVARRA" + deviceAgent; 

return operaAgent ?? deviceAgent ?? hr.UserAgent ?? "Not Found"; 

Bien sûr, si vous ne l'avez pas besoin de préfixer ces chaînes sur les UAs et n'a pas besoin de vous préoccuper avec les agents utilisateurs de chaîne vide, il serait alors simplement:

return hr.ServerVariables["X-OperaMini-Phone-UA"] ?? 
     hr.ServerVariables["X-Device-User-Agent"] ?? 
     hr.UserAgent ?? 
     "Not Found"; 
+0

J'ai complètement oublié l'opérateur coalesce. Bon appel. Sauf un détail: Vous ne gérez pas la partie 'Empty' de' IsNullOrEmpty'. Un détail mineur, certes, un que vous pouvez corriger avec un montage rapide. (Je vous ai encore + 1ed, bonne idée.) –

+0

+1 pour la lisibilité ainsi que la concision; bien que je transformerais la deuxième déclaration 'if' en' else if' (plus court et plus rapide si la première vérification réussit). – tzaman

+2

Cependant, le code est erroné. ! = null n'est pas le même que dans le code original. – Foxfire

1

Je ne vois aucun moyen de raccourcir significativement cela.

Une façon d'économiser quelques lignes est de se débarrasser des accolades autour du premier autre:

if (!String.IsNullOrEmpty(originalBrowser)) 
{ 
    return "OPERAMINI " + originalBrowser; 
} 
else if (!String.IsNullOrEmpty(anotherOriginalBrowser)) 
{ 
    return "NOVARRA " + anotherOriginalBrowser; 
} 
else if (!String.IsNullOrEmpty(visitorBrowser)) 
{ 
    return visitorBrowser; 
} 
else 
{ 
    return "No User Agent Detected"; 
} 

Vous devriez faire attention à utiliser des exceptions pour le contrôle des flux, aussi. statenjason a la bonne idée.

1

À l'heure actuelle, ce que vous avez est clair et lisible. Si vous essayez d'y arriver avec moins de temps de traitement, je ne pense pas que vous allez y arriver. Si vous essayez d'y arriver avec moins de lignes de code, vous le pouvez, mais ça va être moche.

Un moyen facile de le raccourcir à l'écran (même nombre de LOC, -1) est de supprimer certains de vos accolades et non stocker visitorBrowser:

public static string GetUa(HttpRequest hr) 
{ 
    try 
    { 
     string originalBrowser = hr.ServerVariables["X-OperaMini-Phone-UA"]; 
     string anotherOriginalBrowser = hr.ServerVariables["X-Device-User-Agent"]; //novarra 

     if (!String.IsNullOrEmpty(originalBrowser)) 
      return "OPERAMINI " + originalBrowser; 
     else 
      if (!String.IsNullOrEmpty(anotherOriginalBrowser)) 
       return "NOVARRA " + anotherOriginalBrowser; 
      else 
       return hr.UserAgent.ToString(); 
    } 
    catch 
    { 
     return "No UA Found"; 
    } 
} 

Pour moi, ce qui est légèrement moins lisible, mais probablement encore habitable.

Maintenant, vous pouvez le faire vraiment court en utilisant l'opérateur conditionnel (?:), mais il va être aussi vraiment méchant pour une meilleure lisibilité. Si je voyais code comme suit dans une revue de code, je ferais le développeur réécrire pour plus de clarté:

public static string GetUa(HttpRequest hr) 
{ 
    try 
    { 
     string visitorBrowser = hr.UserAgent.ToString(); 
     string originalBrowser = hr.ServerVariables["X-OperaMini-Phone-UA"]; 
     string anotherOriginalBrowser = hr.ServerVariables["X-Device-User-Agent"]; //novarra 

     return !(string.IsNullOrEmpty(originalBrowser)) ? "OPERAMINI " + originalBrowser : 
       !(string.IsNullOrEmpty(anotherOriginalBrowser)) ? "NOVARRA " + anotherOriginalBrowser : visitorBrowser); 
    } 
    catch 
    { 
     return "No UA Found"; 
    } 
} 

Sérieusement, s'il vous plaît ne font pas le second exemple. (Je ne suis pas sûr à 100% que cela se compilera, je l'écris en haut de ma tête sur mon Mac en ce moment .Mais je suis sûr à 99,9% que ça fonctionnera, et le prochain développeur HATE vous pour elle)

+0

Suis-je la seule personne qui trouve cette seconde pièce extrêmement lisible alors? :) – pdr

+0

J'adore l'opérateur conditionnel, mais je * déteste * les enchaîner ensemble. Avec deux conditions, ce n'est pas trop mal, mais avec 3 ou plus, je trouve que la lisibilité manque sérieusement. –

+1

Assez juste. Pour moi, si je peux les aligner comme vous l'avez ici, c'est toujours lisible, peu importe le nombre. Je peux voir qu'il y a un '?' sur chaque ligne, donc je sais ce que tu fais. Je pourrais être tenté de laisser tomber "visiteurBrowser" à sa propre ligne pour dire "c'est le fourre-tout, à la fin ici".Là où je déteste les ternaires enchaînés, c'est là où la chaîne n'est pas toujours à la fin. par exemple. A = 1? B: C = 1? D: E = 1? F: G 'est lisible pour moi' A = 1? B = 1? C: D: E = 1? F: G 'ne l'est pas, même si vous l'insérez entre parenthèses. – pdr

1

Comme cela, par exemple:.

public static string GetUa(HttpRequest hr) { 
    try { 
    string originalBrowser = hr.ServerVariables["X-OperaMini-Phone-UA"]; 
    string anotherOriginalBrowser = hr.ServerVariables["X-Device-User-Agent"]; 
    return 
     !String.IsNullOrEmpty(originalBrowser) ? "OPERAMINI " + originalBrowser : 
     !String.IsNullOrEmpty(anotherOriginalBrowser) ? "NOVARRA " + anotherOriginalBrowser : 
     hr.UserAgent; 
    } catch { 
    return "No UA Found"; 
    } 
} 
0
public static string GetUa(HttpRequest hr) 
{ 
    try 
    { 
     string visitorBrowser = hr.UserAgent.ToString(); 
     string originalBrowser = hr.ServerVariables["X-OperaMini-Phone-UA"]; 
     if (!String.IsNullOrEmpty(originalBrowser)) return "OPERAMINI"+originalBrowser; 
     string anotherOriginalBrowser = hr.ServerVariables["X-Device-User-Agent"]; //novarra 
     if (!String.IsNullOrEmpty(anotherOriginalBrowser)) return "NOVARRA" + anotherOriginalBrowser; 
     return visitorBrowser; 
    } 
    catch 
    { 
     return "No UA Found"; 
    } 
} 
1

Comme cela (tout le reste est juste du code supplémentaire ne rien faire):

public static string GetUa(HttpRequest hr) 
{ 
    if (!String.IsNullOrEmpty(hr.ServerVariables["X-OperaMini-Phone-UA"])) 
     return "OPERAMINI " + hr.ServerVariables["X-OperaMini-Phone-UA"])) ; 
    if (!String.IsNullOrEmpty(hr.ServerVariables["X-Device-User-Agent"])) 
     return "NOVARRA " + hr.ServerVariables["X-Device-User-Agent"])) ; 
    return hr.UserAgent ?? "Not Found"; 
} 

Et vous ne devriez jamais utiliser des exceptions dans votre application normale chemin d'écoulement.

+0

Mais avez-vous obtenu 'originalBrowser' et' anotherOriginalBrowser' de? – Bobby

+0

Surprise, corrigé * g * – Foxfire

+0

Par curiosité laquelle est le plus rapide? Affecter à une chaîne ou demander plusieurs fois le même servervariable? – nLL

1

Voici une version condensée. Puisque vous êtes return ing à l'intérieur de chaque instruction if, vous pouvez éliminer vos else s. En outre, j'ai éliminé le besoin d'utiliser des exceptions pour le flux.

public static string GetUa(HttpRequest hr) 
    { 
     string visitorBrowser = hr.UserAgent; 
     string originalBrowser = hr.ServerVariables["X-OperaMini-Phone-UA"]; 
     string anotherOriginalBrowser = hr.ServerVariables["X-Device-User-Agent"]; //novarra 
     if (string.IsNullOrEmpty(visitorBrowser)) 
      return "No UA Found"; 
     if (!String.IsNullOrEmpty(originalBrowser)) 
      return "OPERAMINI " + originalBrowser; 
     if (!String.IsNullOrEmpty(anotherOriginalBrowser)) 
      return "NOVARRA " + anotherOriginalBrowser; 
     return visitorBrowser; 
    } 
+0

Pourquoi la downvote? – statenjason

0

seconde si-statment:

return (!String.IsNullOrEmpty(anotherOriginalBrowser) ? ("NOVARRA " + anotherOriginalBrowser) : visitorBrowser); 

Vous pouvez probablement utiliser ce combiné avec le premier si-statment trop

0

Je n'aime pas quand il est en train de faire le travail qu'il n » Je dois faire. Donc, je l'écrire comme suit:

public static string GetUa(HttpRequest hr) 
    { 
     string browser = hr.ServerVariables["X-OperaMini-Phone-UA"]; 
     if (!String.IsNullOrEmpty(browser)) 
      return "OPERAMINI " + browser; 

     browser = hr.ServerVariables["X-Device-User-Agent"]; //novarra 
     if (!String.IsNullOrEmpty(browser)) 
      return "NOVARRA " + browser; 

     if (!String.IsNullOrEmpty(hr.UserAgent)) 
      return hr.UserAgent; 

     return "No UA Found"; 
    } 
0

A .NET 4 un peu plus dynamique approche:

private static readonly Tuple<string, string>[] SpecialUas = 
     { 
      Tuple.Create("X-OperaMini-Phone-UA", "NOVARRA"), 
      Tuple.Create("X-Device-User-Agent", "OPERAMINI") 
     }; 

    public static string GetUa(HttpRequest r) 
    { 
     return (
        from specialUa in SpecialUas 
        let serverVariable = r.ServerVariables[specialUa.Item1] 
        where !string.IsNullOrEmpty(serverVariable) 
        select string.Concat(specialUa.Item2, " ", serverVariable) 
       ).FirstOrDefault() ?? (
        string.IsNullOrEmpty(r.UserAgent) 
        ? "No UA Found" 
        : r.UserAgent 
       ); 
    } 

Cela peut être personnalisé avec UAs spéciaux supplémentaires très facilement en ajoutant d'autres tuples.

Il ne serait pas difficile de remplacer les tuples avec quelque chose d'autre si vous n'êtes pas en cours d'exécution sur .NET 4.

Questions connexes