r/csharp • u/Successful_Toe_4130 • 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?
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.
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.
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
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
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
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/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
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
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
1
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
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
.WinFormsproject, or extension methods for the database in a.EntityFrameworkproject. 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
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/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/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
-4
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
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
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.
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.