7

I've got the following class:

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

I know I can use Pages.Home statically, but there is a reason for my question.

I wish to have a method that I can call like this:

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

etc.

C'est possible?

Thanks, Dave

2
  • By the way, you really should mark these fields readonly or use read-only properties instead. Commented Aug 27, 2009 at 11:30
  • const should be avoided, if possible, for the values are not runtime-constant, but compiletime. If you are using private const fields this should not be a problem, but if you are referencing an assembly and use const fields of one of the classes in the assembly, the value is replaced by the literal value of the const field. If you now change the value and just replace the referenced assembly without recompiling the referencing assembly the old value remains in the referencing assembly, which will most likely lead to an undesired behavior. Commented Jan 24, 2014 at 8:02

4 Answers 4

19

You can use the following:

var field = typeof(Pages).GetField("Home", BindingFlags.Public | BindingFlags.Static); var value = (string)field.GetValue(null); 
Sign up to request clarification or add additional context in comments.

1 Comment

string field = typeof(Pages).GetField("Home").GetValue(null); just changed to one line and removed unnecessary bindings.
4

You can do it like Konrad suggested using reflection. But I would consider it much better design to use a dictionary and not rely on reflection for such a task.

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."); } } } 

You should of course adjust the error handling to your actual requirements.

2 Comments

since his original class hard-coded the three page properties, then he could use an enum of those values as keys in the Pages dictionary. helps avoid typos.
Good point if the page collection is static (as the original code suggests).
1

Just my tuppence... if you are going to use literals ("Home"), then I would absolutely bind to the const, i.e. Pages.Home (they should probably be constants in the example given). The reflection approach might be handy if you have:

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

If you do switch to const, then note that they manifest as static fields:

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

If it is used heavily you could also cache these in a dictionary.

Comments

0

As other have said, I'd avoid using reflection here. Also, although it adds a bit more code, an enum for the hardcoded page names is also a good idea (also suggested previously)

 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]; } 

Comments