How can I get all constants of any type using reflection?
Asked
Active
Viewed 9.2k times
208
-
5http://weblogs.asp.net/whaggard/archive/2003/02/20/2708.aspx – David Brabant Apr 21 '12 at 18:38
5 Answers
361
Though it's an old code:
private FieldInfo[] GetConstants(System.Type type)
{
ArrayList constants = new ArrayList();
FieldInfo[] fieldInfos = type.GetFields(
// Gets all public and static fields
BindingFlags.Public | BindingFlags.Static |
// This tells it to get the fields from all base types as well
BindingFlags.FlattenHierarchy);
// Go through the list and only pick out the constants
foreach(FieldInfo fi in fieldInfos)
// IsLiteral determines if its value is written at
// compile time and not changeable
// IsInitOnly determines if the field can be set
// in the body of the constructor
// for C# a field which is readonly keyword would have both true
// but a const field would have only IsLiteral equal to true
if(fi.IsLiteral && !fi.IsInitOnly)
constants.Add(fi);
// Return an array of FieldInfos
return (FieldInfo[])constants.ToArray(typeof(FieldInfo));
}
You can easily convert it to cleaner code using generics and LINQ:
private List<FieldInfo> GetConstants(Type type)
{
FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Public |
BindingFlags.Static | BindingFlags.FlattenHierarchy);
return fieldInfos.Where(fi => fi.IsLiteral && !fi.IsInitOnly).ToList();
}
Or with one line:
type.GetFields(BindingFlags.Public | BindingFlags.Static |
BindingFlags.FlattenHierarchy)
.Where(fi => fi.IsLiteral && !fi.IsInitOnly).ToList();
-
19*My +1* was before i even passed 2nd line ..i noticed you're going through every step with its ...intended-by-design purpose... ! this is **SO** important when one needs to learn from it. i wish every one with your experience would do as you did here . – LoneXcoder Dec 10 '12 at 08:49
-
5I'm not sure about the assertions with regards to IsLiteral and IsInitOnly. On testing it would seem that for static readonly properties IsLiteral is always false - so IsLiteral is the only flag you need to check to find constants and you can ignore IsInitOnly. I tried with different field types (e.g. String, Int32) to see if this made any difference but it did not. – Mark Watts May 05 '15 at 09:55
-
60Also, to get the value of the const from the FieldInfo, use GetRawConstantValue(). – Sam Sippe Jul 07 '15 at 00:15
-
1@MarkWatts is right. May be the behaviour changed since this was posted. In any case documentation of `IsLiteral` says `if its value is written at compile time` and that is true only for constants, which is how it is behaving now (tested as of .NET 4.5.2) – nawfal Dec 23 '19 at 07:46
99
If you would like to get the values of all constants of a specific type, from the target type, here is an extension method (extending some of the answers on this page):
public static class TypeUtilities
{
public static List<T> GetAllPublicConstantValues<T>(this Type type)
{
return type
.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
.Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.FieldType == typeof(T))
.Select(x => (T)x.GetRawConstantValue())
.ToList();
}
}
Then for a class like this
static class MyFruitKeys
{
public const string Apple = "apple";
public const string Plum = "plum";
public const string Peach = "peach";
public const int WillNotBeIncluded = -1;
}
You can obtain the string
constant values like this:
List<string> result = typeof(MyFruitKeys).GetAllPublicConstantValues<string>();
//result[0] == "apple"
//result[1] == "plum"
//result[2] == "peach"

BCA
- 7,776
- 3
- 38
- 53
-
3Why not this: `.Where(fi => fi.IsLiteral && !fi.IsInitOnly).Select(x => x.GetRawConstantValue()).OfType
().ToList();`? – T-moty Oct 26 '18 at 13:08
25
As Type extensions:
public static class TypeExtensions
{
public static IEnumerable<FieldInfo> GetConstants(this Type type)
{
var fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
return fieldInfos.Where(fi => fi.IsLiteral && !fi.IsInitOnly);
}
public static IEnumerable<T> GetConstantsValues<T>(this Type type) where T : class
{
var fieldInfos = GetConstants(type);
return fieldInfos.Select(fi => fi.GetRawConstantValue() as T);
}
}

bytedev
- 8,252
- 4
- 48
- 56
-
1
-
Why not (a) make the methods generic, (b) make the methods return `IEnumerable
` instead of an `IList`? – Wai Ha Lee Dec 11 '15 at 17:06 -
@WaiHaLee - Done :-). Though obviously it still assumes all the types of consts on the class in question are of type T. – bytedev Dec 14 '15 at 10:23
4
Use property.GetConstantValue()
to get value.

Uwe Keim
- 39,551
- 56
- 175
- 291

Reza Bayat
- 393
- 2
- 5
-
2That may well be the case when you *have* the property - but *how* do you first get the property? – Wai Ha Lee Dec 14 '15 at 10:15
-
7
-2
public class Constants
{
public class InputType
{
public const string DOCUMENTPHOTO = "document-photo";
public const string SELFIEPHOTO = "selfie-photo";
public const string SELFIEVIDEO = "selfie-video";
public static List<string> Domain { get { return typeof(Constants.InputType).GetAllPublicConstantValues<string>(); } }
}
public class Type
{
public const string DRIVINGLICENSE = "driving-license";
public const string NATIONALID = "national-id";
public const string PASSPORT = "passport";
public const string PROOFOFRESIDENCY = "proof-of-residency";
public static List<string> Domain { get { return typeof(Constants.Type).GetAllPublicConstantValues<string>(); } }
}
public class Page
{
public const string FRONT = "front";
public const string BLACK = "back";
public static List<string> Domain { get { return typeof(Constants.Page).GetAllPublicConstantValues<string>(); } }
}
public class FileType
{
public const string FRONT = "selfie";
public const string BLACK = "video";
public const string DOCUMENT = "document";
public const string MEDIA = "media";
public const string CAPTCHA = "captcha";
public const string DIGITALSIGNATURE = "digitalSignature";
public static List<string> Domain { get { return typeof(Constants.FileType).GetAllPublicConstantValues<string>(); } }
}
}
public static class TypeUtilities
{
public static List<T> GetAllPublicConstantValues<T>(this Type type)
{
return type
.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
.Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.FieldType == typeof(T))
.Select(x => (T)x.GetRawConstantValue())
.ToList();
}
}
Use: var inputTypeDomain = Constants.InputType.Domain;

Wendell Carvalho
- 15
- 3