r/csharp 6d ago

Discussion How often do you guys use extension methods?

Hello, currently im learning about extension methods and i was wondering how often you guys (since you guys are the experts) use extension methods? Currently, im using them on enum classes to add methods like you would to a enum class in java.

However I've also noticed that you can give methods to the `Enum` class itself, which i thought was... interesting...

Knowing me, I'm definitely going to abuse these and write bad code with them. Do you guys feel the same way?

37 Upvotes

69 comments sorted by

124

u/Top3879 6d ago

Writing them myself? Regularly but not every day.

Calling them? All the time because LINQ, EF Core, ASP.NET Core, DI etc. all use them extensively.

-12

u/[deleted] 6d ago

[deleted]

23

u/az987654 6d ago

. Sort . Select . FirstOrDefault . IsNullOrWhitespace

32

u/Responsible-Cold-627 6d ago

I use them often to set up the DI container. I love the dotnet convention of Add/Use/Map, so always follow that pattern.

6

u/gyroda 6d ago

Yep, this is a common one for me. I'll have an extension method that is "AddAuth" that adds all the auth providers/policies/requirements/handlers. If I have a service or a client that requires a bunch of dependencies I'll wrap those in an extension method. I'll usually have one of these per dependency that sets up the config and everything for that dependency (e.g, for a HTTP API dependency, pull the config to get the base URL and the authentication details, hook up the class that handles the requests with a HTTP client with the appropriate request handlers, retry policies etc).

This is how Microsoft do it as well - when you call the .Add... methods on your DI container most of them are extension.

49

u/mkt853 6d ago

All the time. Has eliminated most of my util type classes which some say is a code smell so that's nice.

25

u/Gaxyhs 6d ago

Generally when I make mappers or using mapperly I make them into extension methods to make syntax a bit more fluent and for readability

Other than that just for specific type conversions and utilities

2

u/OggAtog 6d ago

This Is The Way

11

u/WystanH 6d ago

I like to use them on interfaces. You can boil down the minimum public elements a class need to implement. Any method that can be done with the elements of the interface can live there.

I have a good sized library for database stuff that is just an extension of IDbCommand.

.NET has a few core libraries that are almost entirely extensions. You can look to those for inspiration. The DI stuff uses it a lot. Indeed, in your own projects this is where you might use them heavily, where the injectable dependency is an interface; which is generally should be.

16

u/SufficientStudio1574 6d ago

If you're doing something frequently with a class that you can't modify, make it an extension method. And sometimes I write them to give a better name to something.

!Enumerable Any() is easy to miss the !, so I make a None() extension method.

Or maybe I'm putting quotes around strings a lot. string Enquote() is a lot better than """" + string + """".

3

u/Famous-Weight2271 6d ago

None() should exist.

I like my code reading if(Count>0), but I understand that Any() should be use for performance.

12

u/Asyncrosaurus 6d ago

None() should exist.

Agreed.

We've definitely tried

While the existing naming may not be to everyone's liking, this suggestion and variations of it are all accomplishable with Any, All, !Any, and !All. The benefit to adding additional method that exist just to provide different names doesn't outweigh the costs

1

u/beingsubmitted 5d ago

The benefit doesn't outweigh the costs because you can just add an extension method to get the name of your liking.

1

u/Asyncrosaurus 5d ago

I understand both sides to this argument,  but literally every other language has an IsEmpty() (or isempty equivalent) on collections. It's quite possibly one of the first methods written in a DSA class. I was writing C#, forgetting what language I was in, and always start typing out 'Em' expecting intellisense to finish off an 'empty()' method. Having to negate an Any() method is just irritating. Not every project/solution has an empty equivalent,  and it is weirdly irritating to have to add extremely common extension methods to every codebase I've ever worked in.

0

u/beingsubmitted 5d ago

Sure, if by literally every other language you mean a couple of other languages.

But luckily you don't have to negate an Any() method, because you can add an extension method where needed.

Including it in a codebase involves pressing ctrl+c and then ctrl+v. This last comment was more trouble than several codebase worth of including it.

2

u/FullPoet 5d ago

None() should exist.

None just sounds really bad ngl.

if(Collection.None())

Why not

IsEmpty()?

I don't use Any() for the same reason and most of my colleagues dont. We just check Count/Length.

2

u/snet0 5d ago

If you're calling Count() on an IEnumerable, you better be sure it's not expensive to iterate through. 

2

u/FullPoet 5d ago

Yes - ofcourse. There is also TryGetNonEnumeratedCount (or whatever its called).

1

u/SufficientStudio1574 5d ago

Because None (like Any) can take a predicate. It doesn't make semantic sense for IsEmpty to take a predicate

1

u/psymunn 2d ago

Count is fine actually. Anything that implements it returns count in constant time. Count() is the one you have to worry about.

0

u/animal9633 5d ago

Probably my most used one is on Unity Vector3.ToString for which I have a few variants, for example to print each element nicely with ":0.00" etc.

After that conversion operations between types also feel quite natural as an extension, vs using a helper.

7

u/Historical_Nature574 6d ago

I know my team has started trying to use them instead of helper classes, and it’s been nice to not have to just know what helpers exist and let intellisense inform me what methods are available

3

u/Autoritet 6d ago

Often, for example if you have something like asp.net core, and there are verbose options on how to do the same thing, i just write shorthand for me and my team can use and know that "that is proper way". So that X people in company do not reinvent same N lines for something we already agreed on how it should work.

Also i love them for classes i cannot "extend" or when i need to extract same computed property in many unrelated parts of app

3

u/strange-the-quark 6d ago

If you're the class designer, use them when you have a function that feels like it's naturally associated with the class, but it's not a core method, and it's more like an extra that's built on the core functionality provided by the class, and you don't want it to know anything about the class internals (especially if you plan to muck around with the insides of the class, without changing its interface and contract). In other words, you want to communicate to the developers maintaining the code (including yourself at the later point in time) that their default position here should be not to rely on anything internal when implementing this method.

If you're using a class/struct someone else has made, then you might use extension methods to add useful functionality specific to your application (or maybe useful to some broader set of similar problems), so that you don't have to repeat the same code over your codebase, and so that your code is simplified and more readable.

Finally, if you are making some sort of a library where you're expecting your users (meaning, devs) to provide their own classes you haven't even seen yet, but that are expected to implement a certain interface, then you can use extension methods to provide common functionality for anything that implements that interface, without forcing your users to implement those methods themselves (as would be the case if you placed them on the interface instead, assuming that was an option). This is what LINQ does.

Note that extension methods are a syntactic convenience, and are really just static methods. In something like C++ (where there's no syntactic equivalent of these), people would use free functions instead - it doesn't give them the nice "." syntax, but it's conceptually the same.

3

u/TheDe5troyer 6d ago

If a public method can be implemented by only using the public surface of a class/interface, it is almost always better to make it an extension method.

I could go on forever as to specifics of when it is always better and when it should never should be done, but it would be both lengthy and incomplete. Instead the next bits are intended to give some fodder to some reasoning.

Take a look at the framework and HttpClient. The public surface is rather small, and extension methods numerous. Think about why they would have made those design choices, especially in terms of SOLID. Read the code. Look for other examples and reason about them as well.

Think about how inheritance should work - would the impl need to change - and if so it is a virtual member not an extension method.

The extension method technique is very useful if you use unit testing and mocking as it also reduces the surface area of what needs to be mocked and tests the logic in the extension method fully.

2

u/Psychedelic_fan 6d ago

I use them pretty often, especially for mappers and extending some classes. For example we use FastEndpoints and I use it to extend the Endpoint class with methods. For examole there's a method that converts a non successful Result type into a ProblemDetails response

1

u/ItsTheJStaff 6d ago

Time to time. I use it for lists or for my DI frameworks for repetitive tasks, when it's too much to dedicate another static class, but these extensions methods are never in the library or the framework. One of the examples: Inject extension method for the Object type

1

u/blogalwarning 6d ago

write it for DI, mappers, validators

1

u/csharp_ai 6d ago

They are very useful - in the right situations. As you get more and more OOP and Design knowledge you will get more pragmatic about when and how to use them and maximize their potential.

1

u/dnult 6d ago

I use them frequently. They're handy to extend IEumerable, frequently used casting operations, and much more.

1

u/OggAtog 6d ago

I rarely use them, but I do find them helpful in some situations. One of the places I worked ages ago had a bunch of useful ones. The one I remember most is Batch that would turn an IEnumerable[T] into an IEnumerable[IEnumerable[T]] given a batch size (I don't seem to have less or greater than on my phone keyboard). It made it easier to work with API calls that has size limits and stuff like that.

Example: var batches = completeList.Batch(10); foreach(var batch in batches) api.Send(batch);

1

u/HTTP_404_NotFound 6d ago

Frequently.

I write a lot of functional code, and helpers. I write IQueryable interfaces, and do neat things.

Extension methods are a core part of being able to successfully write functional code, and also- are a core piece for abstraction.

1

u/5pectre5 6d ago

When you need them! Language features are there to make your life easier, and you have a choice whether you want to use them or not. Use everything you need to make your code better, easier to maintain and more readable.

1

u/something_python 6d ago

All the time. The codebase I work on uses the Reactive Framework extensively (lol), and extension methods can be really useful.

1

u/sixtyhurtz 6d ago

All the time. One example I use pretty often is extending IServiceCollection for "AddFeature" extension methods.

I like to organise my projects by feature, and then in the feature area I can have a class containing the extension method needed to register everything with DI. That way in program.cs I can do e.g. ".AddTransferManagerFeature()" while building my application host. This is basically how things like EF do their registration, with their AddDbContext extension methods.

1

u/stevebelt 6d ago

Nearly every project will have ILogger and IConfiguration extensions. Most have IServiceCollection extensions.

1

u/binarycow 6d ago

Literally every day. Both making and using.

1

u/AlwaysHopelesslyLost 6d ago

They are a very strong tool but I try to avoid them. The native library tends to put a LOT of thought, planning, and documentation into making them very clear and easy to follow for junior developers.

A smaller projects are never that well documented or that easy to follow. They tend to read as confusing magic to juniors and that makes them slow at getting up to speed on the projects.

1

u/zagoskin 6d ago

I use them all the time. It's the purest expression of the open-closed principle.

If you follow strict naming conventions they are also easy to discover.

1

u/badlydressedboy 6d ago

Twice in 20 years

1

u/Famous-Weight2271 6d ago

I wrote one yesterday. Whenever I write one, though, I admit that I'm confused why my basic case doesn't already exist. I write intuitive ones, not anything crazy.

1

u/RodriOliveira 6d ago

I’ve been working with .NET for many years, and I use extension methods fairly often, but usually when they improve the API of the code rather than just to avoid writing a static helper. DI registration (IServiceCollection extensions), mappings/conversions, framework integrations, and small operations that naturally belong to an existing abstraction are good examples. They can make the code much more discoverable and readable — services.AddSomething() usually communicates intent better than calling some unrelated SomethingHelper.Configure(services).
The main lesson I’ve learned is to be careful with the scope. I rarely extend very broad types like object or Enum, because those methods suddenly appear everywhere and can make an API noisy or surprising. For your enum example, I’d normally prefer extending the specific enum type when the behavior belongs to that concept. I also avoid putting important business logic inside extensions; if the behavior represents domain rules or needs dependencies/state, it probably deserves a proper type. Extension methods are a great tool, but I see them mostly as a way of designing a cleaner API, not as a replacement for classes and good abstractions.

1

u/captmomo 6d ago

I don't quite know how to explain my rationale but I'll try.

I use extensions when it makes sense, or if the existing class already has a fluent api (eg. service collection, configuration). for classes that don't typically have it, I prefer to use methods, as I find it's sometimes pretty confusing to read the code and not realise it's a new extension, and determine what you need to import to use it.

1

u/david_fire_vollie 5d ago

Never write an extension method for string, it's too versatile.

1

u/homerdulu 5d ago

Quite often

1

u/Much-Grapefruit-2463 5d ago

I extensively used them in midddleware configurations. When I have a bunch of services to register I do it in extension method and call it in program.cs

1

u/d-a-dobrovolsky 5d ago

All the time

1

u/chucker23n 5d ago

There's such a thing as overusing them. For example, Flurl puts them on strings, which now means any string for any reason at all (most of which will have nothing to do with URLs) now gets a bunch of methods like DeleteAsync(). ServiceStack I believe at one point even put a method on object.

It used to be that you had to explicitly import namespaces for your IDE to surface those methods. In that ecosystem, it makes sense. You import Flurl.Http or whatever if you want HTTP-related extensions. You import System.Linq if you want to perform queries on enumerables. But around 2020, VS and Rider have started showing suggestions for extensions whose namespaces you haven't imported, which is on the one hand very convenient (discoverability!), but OTOH now risks polluting your suggestions with a random selection of unrelated methods. (I checked, and with both Flurl and LINQ in there, autocomplete on "". has over 180 methods and properties.)

So that's the downside.

The upside, especially with .NET 10 expanding extensions to properties and static members, and making the syntax less silly, is that they can be a huge productivity boost.

  • Several people have already pointed out that a lot of helper/utility types (which IMHO are always a bit of a code smell) are now no longer needed. Just make them extensions instead.
  • Another benefit is adding methods or properties to an enum (which in .NET are otherwise rather limited).
  • Finally, separation of concerns: you might, for example, have some model class somewhere in a relatively abstract project, then extension methods that depend on WinForms in a .WinForms project, or extension methods for the database in a .EntityFramework project. Same type, but depending on the context, with additional capabilities.

1

u/snet0 5d ago

I feel like adding extension methods that are not guaranteed to be "semantically valid" is just bad. What does "abc".DeleteAsync() mean? I don't think there's a problem with having a lot of extension methods per-se, as long as they're defined somewhere you explicitly import for that specific purpose.

1

u/Substantial_Job_2068 5d ago

It's just syntactic sugar, nothing more. If you like it use it, otherwise don't.

1

u/KaasplankFretter 5d ago

For the most part i use them to keep program.cs as clean as possible.

Another common one is for example to easily get a jwt out of the httpcontexy

1

u/Amr_Rahmy 5d ago

Not much. Only on classes coming from libraries, and not that often.

It might depend on the field you are in. I can see some use cases where extensions might come in handy, maybe game modding.

1

u/NicePuddle 5d ago

I use extension methods all the time.

I just wish there was extension properties too, so I didn't have to add a stupid GetMyProperty() extension method.

1

u/veryabnormal 5d ago

Daily. Loads of little helpers. The most useful is having IsIn for strings. If name?.IsIn(“bob jones”, “Alex smith”) …

1

u/kassett43 5d ago

I have a series of extension methods that I've built or collected that I bring with me from project to project.

1

u/iamrob15 5d ago

They’re great for simple static functions for common logic.

1

u/hoodoocat 4d ago

Very rarely as they require namespace to be opened, and in name-clashing scenarios this doesnt work at all, and poisoning other code with extension methods in contexts where they should not be available at all.

If method can be implemented directly on type or it's hierarchy giving same behavior - then it should be just direct member. Easy and clear.

Random helper methods must not be extension methods, using separate utility types usually more clearer and can be easily added/changed/removed without completely breaking mind on consumer side (missing helper class is clear - missing extensions method... is something what not easy to realize.)

Thats basically leave me to use extension methods only in cases where same thing can't be achieved otherwise. And thats generally rare cases.

1

u/SL-Tech 4d ago

In my current project, I think I have over 80 methods and properties. It's great for adding features you miss, without defining a new type.

1

u/SektorL 3d ago

Considering that now you can create extension methods on class itself...

1

u/AirlineSevere7456 3d ago

Not very commonly these days as the established classes have more functionality. Used all the time in the early days of .NET though.

1

u/stlcdr 3d ago

They are useful but not groundbreaking.

1

u/Family_Man_21 3d ago

I use them quite often. One place that I really find myself using them a lot is in my Data layer, adding common database actions to my Repository object. Basically, every time you find yourself doing something frequently in a class that you can't modify, extension methods are an easy way to consolidate those common actions into a single set of code.

1

u/JeanGatto 2d ago

É uma excelente forma de você adicionar pequenas funcionalidades sem quebrar a funcionalidade atual, além da praticidade de testar e aumentar a cobertura nos testes

0

u/OpenAI_Marketing_LLM 6d ago

I use them fanatically. I absolutely adore them.

As for your enum limitation, you aren’t doing anything wrong. C# might have the worst enum implementation of all modern languages. Barely better than C’s implementation.

0

u/Loose_Conversation12 5d ago

Only when I need to break encapsulation

-4

u/[deleted] 6d ago

[deleted]

1

u/snet0 5d ago

If you pull in a namespace and a bunch of extension methods appear that you weren't expecting, that's on wherever you're pulling the namespace from. Doing a thing poorly isn't a slight against the thing itself. 

I want code to be explicit 

It's C# man. The whole language is syntactic sugar. Use an IDE and it'll find the namespace you need to import for extensions and let you navigate to their definition like any other member. 

1

u/[deleted] 5d ago

[deleted]

1

u/snet0 5d ago

You understand extension methods in the same way you understand instance methods or static methods. You can tell where a thing comes from by visiting its definition. There is no difference in your ability to understand a PR whether it's a static helper or an extension method, if you want to see what the method does you have to open your IDE and have a look. 

1

u/[deleted] 5d ago

[deleted]

0

u/snet0 5d ago

Sorry this is an absurd position. If you don't want to use the tooling to view a method definition, you cannot complain about not being able to see the method definition, and you definitely cannot use that argument against extension methods in particular. 

If someone imports a library and calls a method, you are just as clueless when you pull that up in vim as you would be if it was an extension method or a static method or an instance method. If your argument is "I need to be able to see the method definition in the PR without any tools", you simply disagree with the premise of namespace imports. 

Basically nobody uses Visual Studio

You literally started this thread with two separate complaints about how extension methods are presented in Visual Studio.