I am working on a library that involves retrieving the methods of a given type. I have been using Type.GetMethods
, but I've noticed an issue. Let's say that a method in the given type uses a ConditionalAttribute
, and the value for this condition is false. GetMethods will still include this method, but I would like to ignore it.
Here is a simple example of what I am attempting. This program is ran in Debug mode, so I want to find a way where only foo() and fooDebug() are called while fooBar() is ignored.
using System;
using System.Diagnostics;
using System.Reflection;
namespace ConsoleApplication
{
class ClassA
{
public static void foo()
{
Console.WriteLine("foo");
}
[Conditional("DEBUG")]
public static void fooDebug()
{
Console.WriteLine("fooDebug");
}
[Conditional("BAR")]
public static void fooBar()
{
Console.WriteLine("fooBar");
}
}
class Program
{
//In this example, I want to find a way where only foo() and fooDebug() are called and fooBar() is ignored, when reflected.
static void Main(string[] args)
{
//Call methods directly.
//Methods are called/ignored as expected.
ClassA.foo();//not ignored
ClassA.fooDebug();//not ignored
ClassA.fooBar();//ignored
//Call methods with reflection
MethodInfo[] methods = typeof(ClassA).GetMethods(BindingFlags.Static | BindingFlags.Public);
foreach (MethodInfo method in methods)
{
//All methods are called, regardless of the ConditionalAttribute.
method.Invoke(null, null);
//I figured there would be some workaround like this:
ConditionalAttribute conditional =
Attribute.GetCustomAttribute(method, typeof(ConditionalAttribute)) as ConditionalAttribute;
if (conditional == null)
{
//The method calls if it has no ConditionalAttribute
method.Invoke(null, null);
}
else
{
//I can get the string of the condition; but I have no idea how, at runtime, to check if it's defined.
string conditionString = conditional.ConditionString;
//I also cannnot do a hardcoded (conditionString == "BAR") because the library would not know about BAR
bool conditionIsTrue = true;
//conditionIsTrue = ??
//If the method has a ConditionalAttribute, only call it if the condition is true
if (conditionIsTrue)
{
method.Invoke(null, null);
}
}
}
}
}
}
Ultimately, I would like to know which methods do not include false ConditionalAttributes.
EDIT
This idea is for a library that others would use, so assume that ClassA is a type that they define and pass into my library.
What this basically boils down to is: "can I determine, via reflection, the arbitrary conditional compilation symbols that were used to compile a given piece of code" - AFAIK, the answer to that is "no".
Note: everything under here no longer applies since the edit that makes it clear that the context here is library / caller.
If you have the luxury of being able to move the methods around (and make them non-public), then maybe:
Now, the methods that aren't implemented do not exist after compile, so will not show in the reflection code. Note that you'd need use
BindingFlags.Static | BindingFlags.NonPublic
to find them now, since they are non-public: