0

Poor practice aside, I'm trying to get filter subclasses by their property values.

class Base
{
const string tag = "";
}

class A : Base
{
new const string tag = "ClassA";
}

class B : Base
{
new const string tag = "ClassB";
}

I know that const is implicitly static, and so the tags aren't actually inherited, but instead are just associated with the subclasses.

Then, I want to filter to only Class A:

var result = Assembly.GetAssembly(typeof(Base))
.GetTypes()
.Where(t => t.BaseType == (typeof(Base))
.Where(t => ((string)t.GetProperty("tag").GetValue(null)).ToLower() == "classa")
.FirstOrDefault()

I'm calling GetValue on null because as a static property, I shouldn't call GetValue on an instance. This is from Get value of a public static field via reflection

When I run this code, I get a NullReferenceException. This is not an ideal way of doing this, but I am constrained to getting by assembly and comparing by string. Why would I be getting the null reference?

Jeremy
  • 104
  • 3
  • 12
  • 3
    You can't access constants using reflection as constants are not compiled into the assembly but rather their value is inserted where the constant is referenced. Therefore they have no actual memory representation. However instead of a constant you could use a static readonly field and access this with GetField. – ckuri Jul 27 '17 at 19:57
  • 1
    `const` is not a property. Use `GetField("tag", BindingFlags.Static | BindingFlags.NonPublic)` instead. – Ivan Stoev Jul 27 '17 at 19:58
  • @Ivan Stoev: Constants aren't fields either. – ckuri Jul 27 '17 at 20:00
  • 1
    @ckuri From reflection point of view they are like static fields. Why don't you try and see :) – Ivan Stoev Jul 27 '17 at 20:01
  • @ckuri This is c#, const aren't replaced as they used to in C/C++ etc, they are very well part of Class and it can even be accessed after compilation. – Akash Kava Jul 27 '17 at 20:04
  • Why are you doing this? This smells like an X-Y problem. – xxbbcc Jul 27 '17 at 20:05
  • @Akash Kava and IvanStoev: You are right, I mixed this up with the IL code where references to constants are indeed substituted by their values (https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/constants). – ckuri Jul 27 '17 at 20:14

1 Answers1

2

I think you want to look for fields, and use FieldInfo.GetRawConstantValue()

Matt Warren
  • 1,956
  • 14
  • 15