top | item 35485210

(no title)

nimbix | 2 years ago

I recently got into c# and it seems really nice, but the "customs and traditions" of the dotNet world horrify me (eg: never write a function when you can write three classes instead)

discuss

order

bob1029|2 years ago

You can actually write an entire, complex C# application without using a single class via top-level statements. Named tuples make it easy to wire together functions without invoking the full OO type system.

diarrhea|2 years ago

Very true, but there remains a large gap between what’s technically possible and customarily applied.

oaiey|2 years ago

Which customs and traditions? I work for nearly two decades in the .NET space and it seems I missed that indoctrination. What I see is a developer population moving through time, adapting the technology trends as they come and go and taking the best for the current projects. And so did also the language and platform itself. When I started I needed a Visual Studio on Windows, 3 xml files and at least 10 code classes to startup a simple app. Today, I (can) code/deploy on Linux, use Visual Studio Code (or any editor), my project has two files, zero classes and looks more like nodejs than anything else.

IMHO, there is a huge misconception regards C# regards their OOP enforcement. Most classes you ever write for business logic in C# are nothing more than namespaces/grouping containers. And that is for good. There are so little business logic object hierarchies (aka the Pattern world or OOP fantasy world). The other reason to write classes are object to transfer data (no logic). There are the sinful years of DTOs (which are an OOP abomination) but that is obsolete for some years already in favor of records.

withinboredom|2 years ago

C# is a follower of DDD, mostly. Which is a 'standard' practice for OOP design. I highly recommend reading the book about it, but that is how you end up with many classes instead of a simple function. Also, in C#, you can't generally mock a function (or static method?, not 100% sure on that, it's been nearly 10 years since I've written a unit test in C#).

WorldMaker|2 years ago

> you can't generally mock a function

With `dynamic` and `DynamicObject`/`ExpandoObject` proxies (or even lower level System.Dynamic/System.Linq.Expression fun) you can mock anything you want to in C#.

Those tools go all the way back to the early days of Linq (and useful but somewhat broken DLR visions like IronPython). If you need to time travel even further back in the .NET stack, or if you are just allergic to/deathly afraid of the DLR as some people seem to be, System.Reflection.Emit has been there since day 1. It's awful to work with and even worse low-level experience than the DLR, but it is capable of a lot of things. If you've got an up-to-date compiler you can go the other direction and use the recent Source Generators to do all the same low-level things but this time in the context of Roslyn and at build/compile-time.

Obviously, that doesn't necessarily make it a good idea that just because you can do such things that you should do such things, but C# has far more powerful raw tools at its disposal than many people realize.

A lot of the boilerplate in DDD styles is simply a preference for it and (over-)design patterns as comfort food.

It's a further aside, but hand-written "Fakes" patterns require more up-front work but often seem to me much better than automated Mocks. I've never seen a good DDD pattern focus on good "Fakes", though, and sometimes I find DDD complexity gets in the way of good "Fakes".

nimbix|2 years ago

The scenario I was referring to is one of many gems found in app we outsourced.

The piece of code in question had a very straightforward task: look at some bytes in the input and produce a string label to be stored alongside the whole input value. There are 5 different labels tied to equal number of fixed byte sequences.

I would like to think that most people would solve this problem using an if/else or a switch statement inside a function. Instead, what we got is a group of matcher classes, a mapping of matchers to enum values representing the labels, another mapping of enum values to actual strings, and a class that actually calls those matchers and does the mapping.

I really hope this is not the DDD way and instead we just managed to find a team that's prone to massively overcomplicate solutions to simple problems.

yonaguska|2 years ago

> you can't generally mock a function

Yes, this is generally true, so the workaround is to put your function in a class, and use an interface + dependency injection to mock what you need. Sometimes it's a hassle.

co_dh|2 years ago

What is DDD?

userbinator|2 years ago

That culture is largely shared with Java.