Learn C#: Method Hiding (and Why You Will Want To Avoid It)

Поділитися
Вставка
  • Опубліковано 6 вер 2024
  • Become a sponsor to access source code ► / zoranhorvat
    Join Discord server with topics on C# ► codinghelmet.c...
    Enroll course Beginning Object-Oriented Programming with C# ► codinghelmet.c...
    Subscribe ► / @zoran-horvat
    Learn from related videos:
    How Do Virtual Methods Work? ► • Learn C#: How Do Virtu...
    Abstract or Virtual Method, Which Fits Better Here? ► • Learn C#: Abstract or ...
    Method hiding is one of the most obscure programming techniques in C#. It lets you redefine a method in a derived class without actually overriding it.
    Does method hiding produce polymorphic types? No, it does not. Is it not polymorphic, then? Well, no, sometimes it is. What the hack?!
    Some programmers accept to hide an inherited method with another one with the same signature in an attempt to accomplish various goals. What they fail to understand, though, is that every such implementation can only work as expected in a narrow set of use cases. At the same time, it will behave erratically in other cases.
    Worse yet, in the narrow window of opportunity within which you can effectively invoke a method in the derived class, at least two other programming techniques exist that work as expected under any circumstances! One is to define a method whose name does not conflict with the base class. Another is to apply interface implementation rather than class derivation.
    The world is your oyster if you are ready to ditch method hiding from your tool belt!
    ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
    ⚡️RIGHT NOTICE:
    The Copyright Laws of the United States recognize a “fair use” of copyrighted content. Section 107 of the U.S. Copyright Act states: “Notwithstanding the provisions of sections 106 and 106A, the fair use of a copyrighted work, including such use by reproduction in copies or phono records or by any other means specified by that section, for purposes such as criticism, comment, news reporting, teaching (including multiple copies for classroom use), scholarship, or research, is not an infringement of copyright." This video and our youtube channel, in general, may contain certain copyrighted works that were not specifically authorized to be used by the copyright holder(s), but which we believe in good faith are protected by federal law and the Fair use doctrine for one or more of the reasons noted above.
    #csharp #dotnet #objectorientedprogramming

КОМЕНТАРІ • 41

  • @oolong2
    @oolong2 5 місяців тому +2

    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.

  • @joaogabrielv.m328
    @joaogabrielv.m328 5 місяців тому +7

    "new void" seems like a new way to give programmers a PTSD LOL
    Great video, man

    • @jongeduard
      @jongeduard 5 місяців тому

      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.

  • @fluffydoggo
    @fluffydoggo 5 місяців тому

    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.

  • @chandrahaslanka
    @chandrahaslanka 4 місяці тому +1

    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.

  • @Sindrijo
    @Sindrijo 5 місяців тому +3

    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.

    • @zoran-horvat
      @zoran-horvat  5 місяців тому +2

      Yes, but that is another topic. In this video, I only wanted to show hiding as an isolated concept.

  • @colinhannah2210
    @colinhannah2210 5 місяців тому

    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.

  • @Sindrijo
    @Sindrijo 5 місяців тому +8

    DONT DO IT, YOU WILL REGRET IT.

  • @vitahvitah5823
    @vitahvitah5823 5 місяців тому +1

    Very nice explanation. Thanks

  • @ataadevs
    @ataadevs 5 місяців тому +1

    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

    • @zoran-horvat
      @zoran-horvat  5 місяців тому +1

      Sure. You would use method hiding only when everything else fails.

  • @sagarviradiya
    @sagarviradiya 5 місяців тому +1

    you sounds mysterious!!!

  • @evancombs5159
    @evancombs5159 5 місяців тому +1

    So this begs the questions as to why was this feature included in the first place? Is there a valid use case?

    • @zoran-horvat
      @zoran-horvat  5 місяців тому +2

      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.

  • @nickbarton3191
    @nickbarton3191 5 місяців тому +1

    I didn't know the subtly with the Interface, but we don't allow method hiding, just hideous.
    Doesn't it break LSP?

    • @zoran-horvat
      @zoran-horvat  5 місяців тому

      It doesn't break the LSP per se, but a concrete implementation could. Like with any other method.

    • @nickbarton3191
      @nickbarton3191 5 місяців тому

      @@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.

    • @zoran-horvat
      @zoran-horvat  5 місяців тому +1

      @@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?

    • @nickbarton3191
      @nickbarton3191 5 місяців тому

      @@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.

    • @zoran-horvat
      @zoran-horvat  5 місяців тому +1

      @@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.

  • @C00l-Game-Dev
    @C00l-Game-Dev 5 місяців тому +2

    var thing = new void();

    • @zoran-horvat
      @zoran-horvat  5 місяців тому +3

      That would twist so many brains.

  • @Dr-Zed
    @Dr-Zed 5 місяців тому

    Thanks, I really hate it. But at least you can't attach properties to functions like you can in JavaScript. Yes, JS is that cursed!

  • @EugeneS88-RU
    @EugeneS88-RU 5 місяців тому +1

    Its really head acke

    • @zoran-horvat
      @zoran-horvat  5 місяців тому +1

      And that is the reason enough to never do it.

  • @rankarat
    @rankarat 5 місяців тому +1

    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.

    • @jongeduard
      @jongeduard 5 місяців тому +3

      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.