The problem you are having is not based on whether or not the operator is inherited but due to the return type of the operator.
However in the case of an assigning operator you will have an issue with the return type of the operator
The expression x++ is a short hand for
x = x + 1
And in your case you are returning a Person and trying to assign that to an Agent.
Written out that would be
agent.Age++;
agent = (Person)agent; //the cast is implicit and a result of the return type
You can only assign to a more generalized type. So assigning an Agent to a Person would work which is why the compiler will allow the return type to be a specialization of the implementing type (as is the case below).
You can accomplish what you are looking for with a bit of generics trickery
class Person<T> where T : Person<T>, new()
{
public int Age;
//taking advantage of the fact that the return type might be a specialization
//of the type implementing the operator
public static T operator ++(Person<T> p)
{
return new T { Age = p.Age + 1 };
}
}
class Agent : Person<Agent> { }
//Only required if Person should be usable on it's own
class Person : Person<Person> { }
The above operator constructs a new object which to me is inline with the contract of the ++operator but also requires a default constructor, if you wish you can do it with a cast instead.
public static T operator ++(Person<T> p)
{
p.Age++;
return (T)p;
}
Whether or not the operator is inherited is a matter of how you define inheritance.
The C# specifications uses "inheritance" in a different manner than the CLI specifications. The way the C# specs uses inheritance is in the the context of operators and static methods incompatible with the CLI specification (Ie the C# spec contradict the CLI specifications and as such the platform C# runs on does not support the specifications)
To out line why my money is on "operators are not inherited" is that they are syntax sugar for a static method.
[SpecialName]
public static T op_increment(Person<T> p)
{
return new T { Age = p.Age + 1 };
}
That's the implementation of a static method. According to the CLI specifications then static methods are not inherited:
A derived object type inherits all of the instance and virtual methods of its base object type. It
does not inherit constructors or static methods.
below is an implementation of the ++ operator
public static T operator ++(Person<T> p)
{
return new T { Age = p.Age + 1 };
}
The IL for both of these two implementations is identical