1

Consider following code:

public class Test
{
    [System.AttributeUsage(System.AttributeTargets.Method)]
    class MethodAttribute : System.Attribute
    {
        public MethodAttribute(System.Reflection.MethodInfo methodInfo)
        {

        }
    }

    public void Foo()
    {

    }

    [Method(Test.Foo)] //< THIS IS THE IMPORTANT LINE
    public void Boo()
    {

    }
}

I want to store MethodInfo instance of Foo in attribute of Boo, but problem is, that I cannot use Foo nor Test.Foo to get instance of MethodInfo. I can NOT use typeof(Test).GetMethod("Foo") (not my decision).

Important information:

Absolutely unimportant information:

  • Why I cannot use typeof(Test).GetMethod("Foo"): I'm not allowed. It's not in my power to change this decision. I can not. (Also, personally, I would like to avoid it anyway as it needs to do some lookup instead of getting statically the data. Also it won't be changed automatically during refactoring and will be checking run-time, not compile-time.)
  • Why I want to do this: later in code, I want to create a delegate of Boo() (this time normally, with an instance) and use in special even system or something. Before it's called, this attribute allows to setup method to be called in prepare for main event (it's optional, it can be null) and I know how to create a delegate when I have an object and a method info.
  • Why I cannot just provide both delegates when registering or something: because class containing these methods is not always the one who registers to event source, I need to keep the registration code as simple as possible. In other words, I want to avoid situation when person writing method responsible for connecting forgots to add this preparation delegate.
  • I'm not sure but I think that attributes can contain only compile constant values, so using reflection inside would not compile anyway. –  Aug 27 '14 at 06:57
  • Isn't pointer to MethodInfo constant? I mean, it's not Python, you cannot change pointer to method in a class. Only if it's virtual, but I want the particular Test.Foo MethodInfo and that should be unchanged whole time, am I wrong? I mean, you can't do something like `Test.Foo = Test.Boo` or `Test.Foo = () => ... ;`... –  Aug 27 '14 at 06:59
  • I think it is constant per app domain (may be wrong - can some confirm or decline?) - but in c# there is no way to get `MethodInfo` without using `GetMethod`, `GetMethods` or Expression tree. –  Aug 27 '14 at 07:03
  • Yea, its literally impossible to do what you want to do. Thats why you see attributes referencing methods as string names all the time, not b/c it's pretty but thats just all you can do. – James Aug 27 '14 at 07:05
  • That's sad, but what can I do. Thanks for the info! (Btw. interesting thing is that the code compiles just fine using .Net, but Unity3D is using Mono.) –  Aug 27 '14 at 07:08
  • Update: sorry about the its-compiling-in-.net thing, it's my mistake and buggy MonoDevelop. No, it's not compiling even in .Net. –  Aug 27 '14 at 07:16
  • Attributes are metadata; they are compiled into the assembly at compile-time and do not change during runtime. http://stackoverflow.com/a/10435554/945317 – SomeCode.NET Aug 27 '14 at 09:01
  • @cYounes And methods aren't? –  Aug 27 '14 at 11:51

1 Answers1

0

use expression :

static public class Metadata<T>
{
    static public PropertyInfo Property<TProperty>(Expression<Func<T, TProperty>> property)
    {
        var expression = property.Body as MemberExpression;
        return expression.Member as PropertyInfo;
    }
}

var foo = Metadata<Test>.Property(test => test.Foo);
Teter28
  • 504
  • 5
  • 8