Get Extension methods using reflection!?!

  • Thread starter Thread starter Marc Gravell
  • Start date Start date
M

Marc Gravell

Extension methods *only* exist to the compiler. No changes have been
made to the runtime etc.

I have posted code before showing a way of searching for all possible
matching extension methods by name, but this cannot know which "using"
statements you intended, so is not robust (clashes are very possible;
trivial to demonstrate).

Marc
 
I can't seem to get the extension methods using reflection... They just
don't want to show up. I've read that it is possible and even saw some code
to do it but it doesn't work ;/

If I use the standard method of getting the methods and pass various
BindingFlags I don't get it yet I get the non-extended methods.

Seems you cant use GetMethods to get extentions? (after all, they are not
even in the class)

http://bytes.com/forum/thread755831.html

Of course I can directly call the method

e.g.,

Int32 x;

x.RawWrite(s);
x.GetType().InvokeMember("RawWrite", BindingFlags.InvokeMethod, null, x, new
object[] {s});

First line works fine second gives error about RawWrite not being found.
(I've tried other combinations of flags too)

Are extension just a preprocessing "feature"? Or am I just not passing the
right flags?

Thanks,
Jon
 
Extension methods *only* exist to the compiler. No changes have been
made to the runtime etc.

I have posted code before showing a way of searching for all possible
matching extension methods by name, but this cannot know which "using"
statements you intended, so is not robust (clashes are very possible;
trivial to demonstrate).

Marc

Hi,

You are right, it becomes impossible to detect where they were
declared.
It would be interesting to see how a reflector tool will interprete
them. For example an extension method to the String system class (that
is declared as sealed)
Has anybody test it?
 
message
Extension methods *only* exist to the compiler. No changes have been
made to the runtime etc.

I have posted code before showing a way of searching for all possible
matching extension methods by name, but this cannot know which "using"
statements you intended, so is not robust (clashes are very possible;
trivial to demonstrate).

Marc

Hi,

You are right, it becomes impossible to detect where they were
declared.
It would be interesting to see how a reflector tool will interprete
them. For example an extension method to the String system class (that
is declared as sealed)
Has anybody test it?

AFAIK they can't unless they use some different method... these extensions
just don't show up using GetMethods or even GetMembers. (Unless theres some
combo of flags)

My guess is they will just show the extension as a normal method call
instead as this seems to be what the compiler does internally anyways.
(although maybe the reflector could guess that they are extensions)
 
Reflector etc are fine - foo.SomeExtensionMethod() is simply compiled
as SomeClass.SomeExtensionMethod(foo).

What I meant is that you can't robustly resolve SomeExtensionMethod()
simply by name, as you could have:

namespace A
{
public static class Something
{
public static void Bar(this Foo foo) {...}
}
}
and
namespace B
{
public static class SomethingElse
{
public static void Bar(this Foo foo) {...}
}
}

Now - if you are looking for foo.Bar() at runtime, you have no clue
whether that means A.Something.Bar(foo) vs B.SomethingElse.Bar(foo).
You can only tell at compile time by looking at the using statements
that are in play - and they don't exist once compiled.

Marc
 
It would be interesting to see how a reflector tool will interprete
them.
...
My guess is they will just show the extension as a normal method call
instead
Well, I've got 5.1.0.0 and it shows it using extension syntax -
foo.Bar(), not Something.Bar(foo)
as this seems to be what the compiler does internally anyways
That is exactly what it does
(although maybe the reflector could guess that they are extensions)
No need to guess that they *are* extension methods are marked with
[ExtensionAttribute]. It does, however, have to guess whether you have
used it *as* an extension: in your code, foo.Bar() and
Something.Bar(foo) are identical...
 
Jon Slaughter said:
You are right, it becomes impossible to detect where they were
declared.

Not when you've got code *using* them.
It would be interesting to see how a reflector tool will interprete
them. For example an extension method to the String system class (that
is declared as sealed)
Has anybody test it?

Reflector is dealing with code which is already calling the extension
methods. That's really easy to detect, because it knows exactly the
method being called and can check for the extension attribute.

It won't know whether it was called *as* an extension method or not - I
could write:

new List<string>().Count();
or
Enumerable.Count(new List<string>())

and the compiled code will be the same - but it knows exactly which
method was called and that it *could* have been written as an extension
method.
AFAIK they can't unless they use some different method... these extensions
just don't show up using GetMethods or even GetMembers. (Unless theres some
combo of flags)

That's checking something very different - what extensions are
available on a particular type. That depends on which namespaces and
assemblies are being considered; without a "using System.Linq"
directive, IEnumerable<T> doesn't have a Count() member, for instance.

Of course, you could write your own extension methods for Type which
allowed GetMethods to also take a list of namespaces and assemblies to
search for extension methods :)
My guess is they will just show the extension as a normal method call
instead as this seems to be what the compiler does internally anyways.
(although maybe the reflector could guess that they are extensions)

That depends on what you mean by "as a normal method call". The
compiled code treats them as just static method calls - because that's
what they are.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top