How to Get All Constants of a Type by Reflection

How can I get all constants of a type by reflection?

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

Source

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();

Loop all the constants in a class

Get all public static fields of your type:

Type type = typeof(SiteDetails);
var flags = BindingFlags.Static | BindingFlags.Public;
var fields = type.GetFields(flags); // that will return all fields of any type

You can add IsLiteral filtering if you want to check only constants.

var fields = type.GetFields(flags).Where(f => f.IsLiteral);

Then check if value of any field equals to your value:

string value = "MainCollege"; // your value
bool match = fields.Any(f => value.Equals(f.GetValue(null)));

List all constants of specified class

You may write

private static List<String> getListOfAllStates() {
List<String> list = new ArrayList<String>();

for (Field field : StateOfSomeProcess.class.getDeclaredFields()) {
int modifiers = field.getModifiers();
if( Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers) ) {
list.add(field.getName());
}
}
return list;
}

How to get all constants of a type in Go

If your constants are all in an order, you can use this:

type T int

const (
TA T = iota
TB
TC
NumT
)

func AllTs() []T {
ts := make([]T, NumT)
for i := 0; i < int(NumT); i++ {
ts[i] = T(i)
}
return ts
}

You can also cache the output in e.g. init(). This will only work when all constants are initialised with iota in order. If you need something that works for all cases, use an explicit slice.

C# Get constants from nested classes with reflection

Use GetNestedTypes() instead with the correct BindingFlags for public constants:

var nestedTypes = typeof(MainFoo).GetNestedTypes(BindingFlags.Public);
foreach (Type type in nestedTypes)
{
FieldInfo[] constants = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
// <do stuff here>
}

Using System.Reflection to retrieve a list of const string fields


var dict = typeof(HTDB_Cols).GetNestedTypes()
.First(t=>String.Compare(t.Name,TableName,true)==0)
.GetFields()
.ToDictionary(f => f.Name, f => f.GetValue(null));

To get a list

var list = typeof(HTDB_Cols).GetNestedTypes()
.First(t => String.Compare(t.Name, TableName, true) == 0)
.GetFields()
.Select(f => f.GetValue(null) as string)
.ToList();

Get value of constant by name

To get field values or call members on static types using reflection you pass null as the instance reference.

Here is a short LINQPad program that demonstrates:

void Main()
{
typeof(Test).GetField("Value").GetValue(null).Dump();
// Instance reference is null ----->----^^^^
}

public class Test
{
public const int Value = 42;
}

Output:

42

Please note that the code as shown will not distinguish between normal fields and const fields.

To do that you must check that the field information also contains the flag Literal:

Here is a short LINQPad program that only retrieves constants:

void Main()
{
var constants =
from fieldInfo in typeof(Test).GetFields()
where (fieldInfo.Attributes & FieldAttributes.Literal) != 0
select fieldInfo.Name;
constants.Dump();
}

public class Test
{
public const int Value = 42;
public static readonly int Field = 42;
}

Output:

Value

Get name of constant by value

Simple solution.

Example:

public static class Names
{
public const string name1 = "Name 01";
public const string name2 = "Name 02";

public static string GetNames(string code)
{
foreach (var field in typeof(Names).GetFields())
{
if ((string)field.GetValue(null) == code)
return field.Name.ToString();
}
return "";
}
}

and following will print "name1"

string result = Names.GetNames("Name 01");
Console.WriteLine(result )


Related Topics



Leave a reply



Submit