7

I have an interface with methods annotated with the Pure attribute from System.Diagnostics.Contracts:

public interface IFoo<T> {
    [Pure]
    T First { get; }

    [Pure]
    T Last { get; }

    [Pure]
    T Choose();

    void Add(T item);

    T Remove();
}

I wish to iterate over the members of the interface and check if the member is pure or not. Currently I'm not able to get any attributes from the member info:

var type = typeof(IFoo<>);
var memberInfos = type.GetMembers();
var memberInfo = memberInfos.First(); // <-- Just select one of them
var attributes = memberInfo.GetCustomAttributesData(); // <-- Empty

What am I missing?

Note that I do not have a class or an instance hereof. Only the interface.

Mikkel R. Lund
  • 2,336
  • 1
  • 31
  • 44
  • Check this out - http://stackoverflow.com/questions/540749/can-a-c-sharp-class-inherit-attributes-from-its-interface You may want to reconsider having the attributes on your interface. – Wjdavis5 Apr 07 '16 at 16:16
  • But isn't that question about classes inheriting the attributes? I **only** want to look at the interface and its **members**. – Mikkel R. Lund Apr 07 '16 at 17:36
  • @Wjdavis5 And I don't really have any implementations to look at, only the interfaces. – Mikkel R. Lund Apr 07 '16 at 17:44

1 Answers1

4

Use a decompiler of your choice and open your assembly. You will see that the PureAttribute will be removed by the compiler. So you can not get it with reflection because is does not exist anymore.

To test you can use another attribute that wont get removed and you will be able to get it using reflection.

Update: On the one hand, as you have mentioned in the comments:

Pure is a conditional attribute ([Conditional("CONTRACTS_FULL")]), and is only added if contracts are enable.

On the other hand your code has a flaw because Linqs First() method will return a member without an attribute, the getter method of the property. You can use code like this to get the expected result: members.Where(x => x.GetCustomAttributes<PureAttribute>().Any()).ToArray().

thehennyy
  • 4,020
  • 1
  • 22
  • 31
  • Okay, I see. It is in fact gone. Then tell me: how does Code Contracts know if a method is pure or not? – Mikkel R. Lund Apr 07 '16 at 19:41
  • To be honest, i don't know, maybe there is another or slightly modified compiler in use. – thehennyy Apr 07 '16 at 19:44
  • Oh, wait. Pure is a conditional attribute (`[Conditional("CONTRACTS_FULL")]`), and is only added if contracts are enable. The attribute is actually visible in the assembly (using dotPeeks) if CC are enabled - however, they still do not show up with reflection. – Mikkel R. Lund Apr 07 '16 at 20:02
  • 1
    For me it works `members.Where(x => x.GetCustomAttributes().Any()).ToArray()`. Maybe the member you are getting with linqs `First` returns a member without attribute like a getter method. – thehennyy Apr 07 '16 at 20:22
  • 1
    You're right, that's exactly the problem with using the LINQ `First()` method. The first member is the `get` method for `First`, not the property itself, and the `get` method in fact has no attributes on it. – devuxer Apr 07 '16 at 20:28
  • But of course, what a stupid mistake! Perfect it seems to work now. @thehennyy Do you wanna update your answer to reflect this? – Mikkel R. Lund Apr 07 '16 at 20:46