No – this would violate Liskov’s Substitution Principle. You should always be able to use an instance of a subtype as if it were an instance of a supertype.
Don’t forget that a caller may only be aware of your type “as” the base type or an interface. Consider this code:
object foo = new TypeWithToStringRemoved();
foo.ToString();
That would have to compile, wouldn’t it? Now what would you expect to happen at execution time?
Now for ToString
, GetHashCode
, Equals
and GetType
there’s no way to avoid having them in the first place – but usually if there are methods you want to “remove” from a base type, that suggests you shouldn’t be inheriting from it in the first place. Personally I find the role of inheritance is somewhat overplayed in object oriented programming: where it’s useful it’s really useful, but generally I prefer composition over inheritance, and interfaces as a form of abstraction rather than base classes.