I've only ever used "property hiding" in a derived generic class. Where the base object has a property of type "object" or "SomeOtherBaseClass" but the derived generic version "Derived" would represent that same property as T. It doesn't change how the property works it only casts it to a more specific type.
Unrelated to method hiding, but System.Void is actually a real type, which is used for representing the void internally in dotnet, even though C# does not allow instantiating this type. This is useful for certain usages in Reflection.
I feel like you should have mentioned explicit interface implementation. 1. You can implement a method explicitly only in the interface without resorting to method hiding (because of name clashes). 2. You cannot access this method which would otherwise be hiding a base method through any other means than via the interface. 3. Polymorphism is observed when using the objects via the interface contracts.
I hit the opposite problem recently with the base and derived classes both implementing INotifyPropertyChanged, used to trigger update events in bound WPF user interfaces. We had to refactor away the derived class implementing INotifyPropertyChanged to fix the binding again. Quite subtle.
Thank you so much for this explanation. I come from Java world and I have been racking my brain for days trying to figure out why on earth is this even required. It's completely counterintuitive. And as you mentioned, it is a bad idea overall.
Heres the pattern that revolves around my only use case: public class MyClass(object value) { public object Value { get; } = value; } public class Derived(string value) : MyClass(value) { new public string Value => (string)base.Value; } However I'd rarely write code like this, as I would put MyClass into an interface unless its unfeasible. For example: public interface IConfigurationBinding { object Value { get; } void Serialize(BinaryWriter writer) void Deserialize(BinaryReader reader); } public interface IConfigurationBinding : IConfigurationBinding { new T Value { get; } } public class Int32ConfigurationBinding : IConfigurationBinding { public int Value { get; private set; } object IConfigurationBinding.Value => Value; public void Serialize(BinaryWriter writer) => writer.Write(Value); public void Deserialize(BinaryReader reader) => Value = reader.ReadInt32(); } This way, I can have a list of IConfigurationBindings without knowing their type and I can serialize and deserialize them. I can also check if its a specific type using the type interface. This may be useful in situations where you might read/write the representations of the value differently, or it even can store multiple values. A great example is an implementation using Ticks of DateTime and DateTimeOffset. A class wouldnt work as I could only have one concrete inplementation. The implementing class would implement both IConfigurationBinding, IConfigurationBinding, and IConfigurationBinding. Wish there was a way to change a property nullability without hiding the property as that has come up on occassion.
I did it once, and the manager change the base method to abstract and then used 'override' keyword in the child class. So I learnt my lesson in the hard way
Backward compatibility in seriously forced cases. For example, the generic IEnumerable uses it. I reckon it makes sense if breaking with the name could make rioters with torches and pitchforks appear at your home address. Otherwise, make a breaking change and go clean.
@@zoran-horvat Say that again? If I implemented a new or hiding method which doesn't function like the base method, then running the base class unit tests on an object of that derived class would fail, right? Kind of the benchmark of LSP.
@@nickbarton3191 You must define what "doesn't function like the base method" means. LSP is about proving properties, so you must say which property stops being provable after changing a method. Some method changes might break it; others will preserve it. Very specifically, what makes you think in advance that a unit test would fail if it encountered a changed method implementation? Shouldn't that conclusion depend on the assertion?
@@zoran-horvat Yes, I suppose it depends on the specific test, but changing behaviour risks in any new or overriden method risks that. Maybe that's what you were getting at.
@@nickbarton3191 I am trying to get you to a clear view of method implementations. There is no such thing as "risk" when writing a method. There is a specification of preconditions it must accept as given (and is free to fail when the caller did not oblige); the list of postconditions it must guarantee (that is what we assert in unit tests!); and the list of class invariants it must keep satisfied. Any implementation that satisfies these specifications is by all means valid and no unit test must ever fail on it.
Use AI voice in these videos, your channel will explode. Your content is great, Your voice...not so much, i hate to write it and i feel uncomfortable with what i wrote, but its true and stops from this channel to become what it should become.
Sorry, I feel hard disagree here. I am really tired of all those automatic voices on YT which all sound the same. I really appreciate it when people represent themselves personally. And issues with audio can just be solved by using better audio equipement.