2009-08-27 6 views
5

J'ai la classe suivante:valeur Get de champ statique

public static class Pages 
{ 
    public static string LoggedOut = "LoggedOut.aspx"; 
    public static string Login = "Login.aspx"; 
    public static string Home = "Home.aspx"; 
} 

Je sais que je peux utiliser Pages.Home statiquement, mais il y a une raison de ma question.

Je souhaite avoir une méthode que je peux appeler comme ceci:

string pageName = Pages.GetPage("Home"); 

etc.

C'est possible?

Merci, Dave

+0

Soit dit en passant, vous * vraiment * devrait marquer le readonly' ou l'utilisation de ces champs propriétés en lecture seule à la place. –

+2

... ou 'const' –

+0

' const' devrait être évité, si possible, car les valeurs ne sont pas constantes à l'exécution, mais compiletime. Si vous utilisez des champs 'const' privés, cela ne devrait pas poser de problème, mais si vous faites référence à un assembly et que vous utilisez les champs' const' de l'une des classes de l'assembly, la valeur est remplacée par la valeur littérale du 'const 'champ. Si vous modifiez maintenant la valeur et que vous remplacez simplement l'assembly référencé sans recompiler l'assembly de référence, l'ancienne valeur reste dans l'assembly de référence, ce qui entraîne très probablement un comportement indésirable. –

Répondre

16

Vous pouvez utiliser les éléments suivants:

var field = typeof(Pages).GetField("Home", BindingFlags.Public | BindingFlags.Static); 
var value = (string)field.GetValue(null); 
+0

merci, c'est parfait. –

1

Juste mon tuppence ... si vous allez utiliser littéraux ("Home"), alors je ne serais absolument se lier à le const, soit Pages.Home (ils devraient probablement être des constantes dans l'exemple donné). L'approche de réflexion peut être pratique si vous avez:

string s = ...something clever... 
string page = GetPage(s); 

Si vous faites passer à const, puis notez qu'ils manifestent les champs statiques:

string s = ...something clever... 
FieldInfo field = typeof(Pages).GetField(s, 
    BindingFlags.Static | BindingFlags.Public); 
string page = (string)field.GetValue(null); 

S'il est largement utilisé, vous pouvez aussi Cachez-les dans un dictionnaire.

4

Vous pouvez le faire comme Konrad a suggéré d'utiliser la réflexion. Mais je considérerais qu'il est préférable de concevoir un dictionnaire et de ne pas compter sur la réflexion pour une telle tâche.

public static class Pages 
{ 
    private static readonly IDictionary<String, String> PageMap = null; 

    private static Pages() 
    { 
     Pages.PageMap = new Dictionary<String, String>(); 

     Pages.PageMap.Add("LoggedOut", "LoggedOut.aspx"); 
     Pages.PageMap.Add("Login", "Login.aspx"); 
     Pages.PageMap.Add("Home", "Home.aspx"); 
    } 

    public static GetPage(String pageCode) 
    { 
     String page; 
     if (Pages.PageMap.TryGet(pageCode, out page) 
     { 
      return page; 
     } 
     else 
     { 
      throw new ArgumentException("Page code not found."); 
     } 
    } 
} 

Vous devez bien sûr adapter le traitement des erreurs à vos besoins réels.

+0

étant donné que sa classe d'origine codait en dur les propriétés de trois pages, il pouvait utiliser une énumération de ces valeurs comme clés dans le dictionnaire Pages. permet d'éviter les fautes de frappe. –

+0

Bon point si la collection de pages est statique (comme le suggère le code original). –

0

Comme d'autres l'ont dit, j'éviterais d'utiliser la réflexion ici. En outre, même si elle ajoute un peu plus de code, un ENUM pour les noms de page hardcoded est aussi une bonne idée (également suggéré précédemment)

public enum pages { LoggedOut, Login, Home } 

    static Dictionary<pages, string> pageDict = new Dictionary<pages, string>() { 
     {pages.Home, "Home.aspx"}, 
     {pages.Login, "Login.aspx"}, 
     {pages.LoggedOut, "LoggedOut.aspx"} 
    }; 

    public static string getPage(pages pageName) 
    { 
     return pageDict[pageName]; 
    } 
Questions connexes