HCL
HCL

Reputation: 36775

Show a warning when only one of a pair of methods or properties is overridden

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

Answers (3)

user1023602
user1023602

Reputation:

Write code which has the same effect as enforcement.

  • Make an interface containing the methods/properties you want to override.
  • Write one (overridable) function which returns the interface.
  • So when that is overridden, all the functions are replaced at once.

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

MakePeaceGreatAgain
MakePeaceGreatAgain

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

Stefan Steinegger
Stefan Steinegger

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

Related Questions