Veit's Blog

Hej! đź‘‹ Welcome to my curated space of insights on software development and the tapestry of life.

Java vs. C#: Inheritance of annotations

2015-03-14

Recently a friend and I came over with the idea to blog a series of Java vs. C#. Everything related to this topic you’ll find on the internet is too superficial. We are experienced in both technologies and environments (although my friend is more a .NET guy and my daily bread is Java EE) and could provide a more detailed point of view.

Built-in-annotations in Java are not inherited. I think there is no need for an code example because it’s a fact :). But for your own annotations, there is a way to inherit them with the @Inherited-annotation.

Here is an example:

@Inherited
public @interface GreatestAnnotationEver{
}
@GreatestAnnotationEver
public class BaseClass{ 
... 
}
public class SubClass extends BaseClass { 
... 
}

The class “SubClass” inherits the annotation “@GreatesAnnotationEver” from “BaseClass”. This wouldn’t be the case, if you leave out the “@Inherited” annotation in the “@GreatesAnnotationEver” annotation.


Annotations in C# are inherited to their sublcasses with one exception: If you declare a virtual property with an annotation in the base class, the sub class will lose this annotation if you’re overwriting them.

namespace InheritanceOfAnnotations
{
    using System;
    internal class AnnotateAttribute : Attribute
    {
    }
}
namespace InheritanceOfAnnotations
{
    internal class BaseClassWithAnnotations
    {
        [Annotate]
        public int AnnotatedProperty { get; set; }

        [Annotate]
        public virtual int VirtualAnnotatedProperty { get; set; }

        [Annotate]
        public void AnnotatedMethod()
        {
        }

        [Annotate]
        public virtual void VirtualAnnotatedMethod()
        {
        }
    }
}
namespace InheritanceOfAnnotations
{
    using System.ComponentModel;

    internal class DerivedClass : BaseClassWithAnnotations
    {
    
        public override int VirtualAnnotatedProperty
        {
            get
            {
                return base.VirtualAnnotatedProperty;
            }
            set
            {
                base.VirtualAnnotatedProperty = value;
            }
        }

        [Description]
        public override void VirtualAnnotatedMethod()
        {
            base.AnnotatedMethod();
        }
    }
}
// Annotations are inherited.
// Only virtual overridden properties lose their annotations.
namespace InheritanceOfAnnotations
{
    using System;
    using System.Reflection;

    internal class Program
    {
         private static void CheckAttribute(MemberInfo memberInfo)
        {
            var attributes = memberInfo.GetCustomAttributes(true);
            if (attributes.Length == 0)
            {
                return;
            }

            Console.WriteLine();
            Console.WriteLine("Member '{0}' has attributes:", memberInfo.Name);

            foreach (object attribute in attributes)
            {
                Console.WriteLine("\t - '{0}'", attribute);
            }
        }

        private static void CheckAttributesOfMethodsFromType(Type t)
        {
            Console.WriteLine(t.Name);
            Console.WriteLine("=========================================");
            Console.WriteLine();

            CheckAttribute(t.GetMethod("AnnotatedMethod"));
            CheckAttribute(t.GetMethod("VirtualAnnotatedMethod"));
            CheckAttribute(t.GetProperty("AnnotatedProperty"));
            CheckAttribute(t.GetProperty("VirtualAnnotatedProperty"));

            Console.WriteLine("=========================================");
            Console.WriteLine();
            Console.WriteLine();
        }

        private static void Main(string[] args)
        {
            Type t = typeof(BaseClassWithAnnotations);
            CheckAttributesOfMethodsFromType(t);

            t = typeof(DerivedClass);
            CheckAttributesOfMethodsFromType(t);

            Console.WriteLine("The 'VirtualAnnotatedProperty' loses their attributes.");
            Console.WriteLine("The 'VirtualAnnotatedMethod' has now two attributes.");
            Console.WriteLine("Because the derived class adds the 'Description' attribute.");
            Console.ReadKey();
        }
    }
}