SFML community forums

Bindings - other languages => DotNet => Topic started by: DumpsterDoofus on December 27, 2019, 09:36:23 pm

Title: Is it bad practice to subclass primitives like Text?
Post by: DumpsterDoofus 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?
Title: Re: Is it bad practice to subclass primitives like Text?
Post by: ross 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);
}
 


Title: Re: Is it bad practice to subclass primitives like Text?
Post by: DumpsterDoofus 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!