Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Is it bad practice to subclass primitives like Text?  (Read 9911 times)

0 Members and 1 Guest are viewing this topic.

DumpsterDoofus

  • Newbie
  • *
  • Posts: 2
    • View Profile
Is it bad practice to subclass primitives like Text?
« on: December 27, 2019, 09:36:23 pm »
I sometimes write classes like this:

public class FpsText : Text
{
    private readonly MovingAverage _movingAverage = new MovingAverage(30);
    private readonly Clock _clock = new Clock();

    public FpsText(Font font, uint characterSize) : base("CURRENT FPS 60.00", font, characterSize) =>
        Style = Styles.Italic;

    public void Update()
    {
        _movingAverage.Update(_clock.Restart().AsSeconds());
        DisplayedString = $"CURRENT FPS {1/_movingAverage.Average:F2}";
    }

    public new void Dispose()
    {
        base.Dispose();
        _clock.Dispose();
    }
}
 

Since SFML.Graphics.Text.Dispose() is not marked virtual, I have to apply the new keyword to ensure both the text itself and the clock are disposed.

This works fine when it is known that the type is the subtype. However, this breaks when the runtime type is the subtype but the compile-time type is the supertype. For example, if you insert an FpsText into a List<Text> and then iteratively dispose each text, the clock is not disposed, causing a minor memory leak.

The fact that Dispose() is not marked virtual makes me think subclassing built-in types was not intended by the designers.

Is it bad practice to subclass primitive types, like Text? If so, what's the preferred approach? Should I favor composition over inheritance?
« Last Edit: December 27, 2019, 11:01:29 pm by DumpsterDoofus »

ross

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Is it bad practice to subclass primitives like Text?
« Reply #1 on: July 20, 2020, 11:35:19 pm »
sorry to necro this thread but I think this requires an answer.

I do recommend composition but SFML.Net classes do have the facility for inheritable dispose calls. It follows the documented disposal pattern but for whatever reason SFML.Net doesn’t follow the actual naming convention.

You want to override the Destroy function and add your dispose calls there, don’t forget to call base afterwards.

As you found you should NEVER method hide dispose with the new keyword as you run the risk of the “new” Dispose function not actually getting executed as it’s a non-virtual override for lack of a better term.

protected override void Destroy(bool disposing)
{
    _clock.Dispose();
    base.Destroy(disposing);
}
 



DumpsterDoofus

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Is it bad practice to subclass primitives like Text?
« Reply #2 on: July 28, 2020, 04:19:25 am »
Thanks, Ross! After looking at https://github.com/SFML/SFML.Net/blob/2.5/src/SFML.System/ObjectBase.cs#L51 that explanation makes sense. Will make sure to override "Destroy" instead of "Dispose" from now on!