views:

81

answers:

2

I use Type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) to retrieve an array of methods for a given type.

The problem is the returned MethodInfo could include methods that are generated by the compiler which I don't want. For example:

  • property bool Enabled { get; } will get bool get_Enabled()

  • event SomethingChanged will get add_SomethingChanged(EventHandler) and remove_SomethingChanged(EventHandler)

I can probably add some filter logic to get rid of them which could potentially get very complicated. I want to know if there is something else I can do, such as with BindingFlags settings, to retrieve only user defined methods?

+5  A: 
typeof(MyType)
    .GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
    .Where(m => !m.IsSpecialName)
Yuriy Faktorovich
I did not take concurrency into consideration, but what is it that make using both concurrently dangerous? When googling, I did see some earlier forum posts saying IsSpecialName being unreliable in some instances, but since they were talking about it in the context of .NET 1.0 I just assumed this problem was addressed before or in 3.5.
Dan7
+2  A: 

I think your best bet would be to filter out methods that have the CompilerGenerated attribute. This is likely to be more future-proof, although that doesn't account for hypothetical future compilers disrespecting this attribute entirely. The IsSpecialName test is probably also required since it appears as though the C# compiler does not attach the attribute to event add and remove methods.

Ani
You could use `Where(m => !m.GetCustomAttributes(typeof(CompilerGeneratedAttribute), true).Any())` to filter them. It doesn't seem clear if my answer or your answer is better.
Yuriy Faktorovich
Hey. After a few more testing I was mistaken that CompilerGenerated attribute works, actually it doesn't. My getter/setter/add/remove methods do not have this attribute. Weird. Perhaps it's only attached to auto-implement methods? And setter/getter methods that have user implementation do not get this attribute.
Dan7
@Dan7 did you find it worth it to use both methods concurrently? It doesn't seem like people agree on which is the best way.
Yuriy Faktorovich
@Dan7: This is really about what you consider 'compiler-generated.' In one sense, *all of the code* is compiler-generated. As I understand it, you wish to exclude property getters/setters because you don't consider them to be 'real' methods. On the other hand, the compiler only considers that it is 'generating' them when it is explicitly providing their bodies. This is why only auto-generated properties are marked with the attribute. Now, if you want to exclude methods generated for lambda-expressions etc, you will have to filter on the attribute as well. As I say, depends on your definition.
Ani
@Ani: Good point. Now since you explained it, my wording does look a bit inaccurate. I changed the title, but left the question body intact so future readers won't be confused over what we're discussing. Anyway thanks for the contribution. Even though the attribute does not solve the original problem, I still learned a thing or two about it. :)
Dan7
@Yuriy: I will add write the reply comment under your question instead.
Dan7