5

I've read from plenty of places that attributes defined in interface DO NOT apply to implementing classes, and simply get ignored:

However, it seems like that attributes DO apply to implementing classes:

using Newtonsoft.Json;

interface TestInterface
{
    [JsonProperty(PropertyName = "foo")]
    string id { get; set; }
}

class Test : TestInterface
{
    public string id { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(JsonConvert.SerializeObject(new Test()));
    }
}

Console Output: {"foo": null}

In the above example, JsonProperty attribute is clearly being applied in the implementing class (changing "id" field name to "foo" for serialization).

Did the behavior of C# attributes in interface change or am I missing something?

SHH
  • 3,226
  • 1
  • 28
  • 41
  • Attributes are queried using reflection. It's up to the code which does the query whether to check the inheritance tree or not. So, the question is, "ignored by *what*"? (and I guess JSON.net checks the tree - other libraries may not) – Blorgbeard Oct 17 '17 at 23:52
  • If you look at the link "Attribute on Interface members does not work", the author has a code where attributes do not apply from interfaces, but works from abstract classes. So, it seems like attributes were NOT available via reflection on interface-implementing classes before... (but now it is working via my example) – SHH Oct 17 '17 at 23:56
  • In that case, perhaps JSON.Net actually enumerates the implemented interfaces and checks for attributes manually.. Can you try querying the attribute yourself? – Blorgbeard Oct 17 '17 at 23:59

1 Answers1

8

The attributes are queried via reflection and can be accessed in whatever way the developer wants to. To show proof of how this works in your example code, I had a look at the NewtonSoft.Json source to see how it loaded this value.

The way it gets the JsonProperty attribute is by calling the following on a MemberInfo.

JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(member)

The source for this method at the time of this question can be seen here

As you can see on lines 364-376, it loops over the MemberInfo's interfaces, then tries to get the attribute from the interface if it is unable to load the JsonProperty from the class it is being used on.

Cameron Aavik
  • 812
  • 7
  • 21
  • Thanks for the prompt answer and the reference to the code. How good of them to actually take a look at the interface to pull out JsonProperty attributes when they are missing :) – SHH Oct 18 '17 at 00:16