Reputation: 36775
I have a c#-class which provides virtual operations. For each operation exists a synchronous and an asynchronous version.
public class Foo{
public virtual void Bar(){..};
public virtual Task BarAsync(){..};
...
}
I would like to have the compiler showing a warning if only one version of the operation is overridden (the synchronous or the asynchronous version of the operation) such as the compiler warns when one overrides Equals
without overriding GetHashCode
or vice versa.
Questioned more broadly: Is it possible to enforce that overriding one method or property enforces the overriding of other properties or methods (via compiler warnings).
Upvotes: 9
Views: 220
Reputation:
Write code which has the same effect as enforcement.
Example:
public interface IBarMethods
{
void Bar();
Task BarAsync();
}
public class Foo
{
public virtual IBarMethods DeMethods()
{
// return class containing default methods.
}
}
public class ImplementIt : Foo
{
public override IBarMethods DeMethods()
{
// return different methods.
}
}
Upvotes: 1
Reputation: 37000
Although this is not an answer to your actual question I´m asking for an approach where you do not even need the warning.
Why not create one abstract classes with overridable members and one sealed without:
public class Foo{
public virtual void Bar(){..}
public virtual Task BarAsync(){..}
}
public abstract class ImplementIt : Foo {
public abstract override void Bar();
public abstract override Task BarAsync();
}
public sealed class DoNotImplementIt : Foo {
public override void Bar() {..}
public override Task BarAsync() {..}
}
Now client can design if he needs an implementation of Foo
whith your default behaviour (= DoNotImplementIt
) or if he needs a customizable version using ImplementIt
. In the former case he is forced to override the members in the latter case not.
This approach is far cleaner to your API-user as he knows what to override from the inheritance-chain instead of relying on messy warnings which no-one actually even takes care of.
An even better approach would be to define Foo
as an interface which both ImplementIt
and DoNotImplementIt
implement (sounds weird, however you get it). Saves you from this abstract override
. This way you can also hide your interface from the outside by making it internal
and only make make the implementing classes accessable from the API.
Upvotes: 3
Reputation: 64628
You could write a custom Code Analyzer. I've never used it myself. We started using FxCop and have written a few custom rules for it. But it's quite hard to do. With Roslyn, this should be much easier.
Upvotes: 0