Skip to content

Your Framework, Your Rules: Why I Use Extends for Everything

Over the weekend, I was deep into a side project, parsing a massive server log dump. Strings were everywhere: timestamps were mangled, JSON blobs were half-broken…I kept writing these clunky utility calls, nesting functions inside functions, my code was turning into a sideways pyramid of parentheses.

Then I remembered Extends.

It’s one of those features that sits quietly in the language. But once it clicks, it changes how you think about utility code entirely. Using Extends, within twenty minutes, my nested mess became readable.

Extends Methods in Practice

You know the feeling. You’re writing ParseLogEntry(rawLine) for the hundredth time, and something feels off. The function works. It’s in your Utilities module (maybe part of a Library?). But every time you call it, there’s this tiny friction. Why doesn’t String just know how to parse itself into a log entry? That’s what Extends fixes.

It lets you teach existing classes new tricks. You write a method in a module, tag the first parameter with Extends, and suddenly StringDateTimeDictionary (whatever you need) behaves like it always had that method. No subclassing. No wrapper classes. Just the framework, extended to fit your brain.

Reading The Code

Code is read far more than it’s written. We both know this. But we still write code that reads backwards.

// The old way
Var result As DateTime = ExtractTimestamp(CleanLogEntry(rawLine))

// With Extends
Var result As DateTime = rawLine.CleanLogEntry.ExtractTimestamp

When you’re debugging at 2 AM, tracing logic through nested function calls is the last thing you want. Extension methods turn that horizontal scan into a vertical one.

When Extends is Exactly Right

I don’t use Extends for everything; it’s not a replacement for proper inheritance or composition. But there are specific moments when it’s exactly right.

Built-in types that need one more method. For my log parser, I needed to extract timestamps, clean junk characters, and pull out ISO dates. So, I extended the String class with my custom utilities and made it feel native.

Framework classes you can’t touch. You can’t subclass everything, but Extends can work around things like things third-party plugins, legacy code.

APIs you wish existed. I’ve lost count of how many times I’ve wanted a property or method on a framework class that just isn’t there. Extends lets me do just that.

For practical examples like email validation, URL validation, and dictionary helpers, check out this article that walks you through real implementations. If you want code you can copy into your project today, it’s a good place to start.

A Few Things To Keep In Mind

Nil doesn’t forgive. Call an extension on a Nil object and you’ll get a NilObjectException before your method even runs. The extension sits on the right side of the dot. That object needs to exist.

No override. You can’t replace built-in methods. If you try creating an extension with the same name as an existing method, the compiler will use the original. That’s a good thing; it means you can’t accidentally break framework behavior.

No properties. Extensions add behavior, not state. If you need to store data, you still need a subclass or a wrapper.

Stay organized. Put extensions in well-named modules like LogParsingExtensions or StringHelpers. Six months from now, you’ll want to know where that .ExtractTimestamp method came from.

Dependencies can hide. Extension methods live in modules and behave like native methods, so it’s not always obvious which module a class depends on. Good naming helps.

Trying Extends

If you’ve never written an extension method, take five minutes. Add a module to your project and create a method like this:

Public Function ExtractFirstISODate(Extends source As String) As DateTime
  Var rx As New RegEx
  rx.SearchPattern = "(\d{4}-\d{2}-\d{2})[Tt]?(\d{2}:\d{2}:\d{2})"
  
  Var match As RegExMatch = rx.Search(source)
  If match <> Nil And match.SubExpressionCount > 1 Then
    Var datePart As String = match.SubExpressionString(1)
    Var timePart As String = match.SubExpressionString(2)
    Var isoString As String = datePart + " " + timePart
    
    Try
      Return DateTime.FromString(isoString)
    Catch err As RuntimeException
      Return Nil
    End Try
  End If
  Return Nil
End Function

Now you can call it directly on any string:

Var logLine As String = "[2025-08-14T14:32:15] ERROR: Connection timeout"

Var timestamp As DateTime = logLine.ExtractFirstISODate

If timestamp <> Nil Then
  MessageBox("Found timestamp: " + timestamp.ToString)
Else
  MessageBox("No valid timestamp found")
End If

That’s it. No utility class to instantiate. No module name to remember. Just stringVar.ExtractFirstISODate.

For more complete examples, check out the Extension Methods topic in the Xojo Documentation.

Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!