Decompiling the New C# 14 field Keyword
61 points
4 days ago
| 5 comments
| blog.ivankahl.com
| HN
Kwpolska
6 hours ago
[-]
> If you want to avoid this issue altogether, consider using a source generator library like Mapster. That way, mapping issues can be caught at build time rather than at runtime.

The only winning move is not to play. Mapping libraries, even with source generators, produce lots of bugs and surprising behavior. Just write mappers by hand.

reply
rickstanley
2 hours ago
[-]
We've been using Mapperly (https://mapperly.riok.app/), after a migration from AutoMapper, in our production application. I'm having a good experience, and we kind of like the holistic of this library.

So far, there have been no surprises, and the library warns about potential issues very explicitly, I quite like it.

Of course, if it's just a handful of fields that need mapping, than write manually is the way to go, specially if said fields require a custom mapping, where the library would not facilitate.

reply
default-kramer
1 hour ago
[-]
Every time I've worked on a project that used AutoMapper, I've hated it. But I'll admit that when you read why it was created, it actually makes sense: https://www.jimmybogard.com/automappers-design-philosophy/

It was meant to enforce a convention. Not to avoid the tedium of writing mapping code by hand (although that is another result).

reply
m_fayer
3 hours ago
[-]
2025 version: write mapping functions by llm.
reply
mrsmrtss
5 hours ago
[-]
Agree, mapping libraries make things only more complicated and harder to debug.
reply
materialpoint
3 hours ago
[-]
Auto mappers sincerely need to go away. They work kind of fine initially, but at the first custom field mapping or nested field extraction, you have to invest hours into mostly complete failures of unecessary DSLs in order to something that is extremely trivial to do in basic C#, and often it is impossible to shoe horn the necessary mapping into place. Then you have to deal with package upgrades which regularly rewrite custom mapping logic, and to be sure you have to write additional tests just to hand hold. With multi-caret editors and regex there is no need for automappers. You can write a mapping once and forget about it.
reply
rafaelmn
1 hour ago
[-]
>so preoccupied with whether or not they could, they didn't stop to think if they should

This describes more than half of .net community packages and patterns. So much stuff driven by chasing "oh that's clever" high - forgetting that clever code is miserable to support in prod/maintain. Even when it's your code, but when it's third party libs - it's just asking for weekend debugging sessions and all nighters 2 months past initial delivery date. At some point you just get too old for that shit.

reply
drysart
6 hours ago
[-]
All of the caveats basically boil down to "if you need to access the private backing field from anywhere other than the property getter/setter; then be aware it's going to have a funky non C# compliant field name".

In the EF Core and Automapper type of cases, I consider it an anti-pattern that something outside the class is taking a dependency on a private member of the class in the first place, so the compiler is really doing you a favor by hiding away the private backing field more obscurely.

reply
pwdisswordfishy
5 hours ago
[-]
I'm surprised there isn't something pseudorandom thrown in for good measure – like a few digits of a hash of the source file.
reply
Radle
2 hours ago
[-]
The trick with using characters which by definition are not allowed inside variable names, "<" and ">", should be sufficient no?
reply
kg
53 minutes ago
[-]
I believe the reason for this is that it would break deterministic builds.
reply
kgklxksnrb
46 minutes ago
[-]
dotnet build is’t deterministic as default. Never has been.
reply
materialpoint
3 hours ago
[-]
Serialization is a pretty good cause.
reply
NetMageSCW
1 hour ago
[-]
Serialization shouldn’t be dependent on the name of the backing field.
reply
politelemon
5 hours ago
[-]
I can appreciate the steady syntactic sugar that c# has been introducing these past years, they never feel like an abrupt departure from the consistency throughout. I often think that this is what java could have been if it hadn't been mangled by oracle's influence, unfortunately as much I like java it's pretty obvious that different parts have been designed by disjointed committee members focused on just one thing.
reply
materialpoint
4 hours ago
[-]
This started long before Oracle and the favouring of verbose, ritualistic boiler code was set back at Sun. James Gosling has been staunchly against overloading operators, properties and value types (almost out of spite from Microsoft's success with providing this in C#), the aftermath of which the language and run-time still struggle today and forever will. It's unfortunate that the original inventor, while a brilliant programmer himself, thought so little of others that such features were not to be included, because other programmers might mess up their use.
reply
GuuD
1 hour ago
[-]
I feel like in a few more years and 2-3 major versions C# will have all the useful features of F#. It will also keep being much more exciting because our benevolent corporate visionaries manage to add new gotchas with every major and some minor releases
reply
twoodfin
5 hours ago
[-]
How does C# the language or C# the language standard evolution process accommodate a new keyword with such a generic name? Is it context-dependent?
reply
janjones
4 hours ago
[-]
Yes, it's contextual. There is more details in this section of the article: Naming Conflicts with Existing Class Members
reply
twoodfin
4 hours ago
[-]
Thanks, my bad. I didn’t continue reading past the sections on Entity Framework and AutoMapper.
reply
estimator7292
4 hours ago
[-]
It's been a while, but from memory I think C# allows you to override keywords and use them as variable names when prefixed with @

The compiler knows what you're doing. A keyword like 'field's inside a function's braces just isn't valid. Putting 'field' after a type name in a variable declaration makes as much sense as 'private int class;'

reply
kkukshtel
4 hours ago
[-]
This is the first time they've done this in a long time fwiw. So the answer is "they usually never worry about this because it never happens".

That said, they will also throw compiler warnings in console during build if you are using an all lowercase word with some small number of characters. I don't remember the exact trigger or warning, but it says something like "such words may be reserved for future use by the compiler" to disincentivize use.

reply
lillecarl
4 hours ago
[-]
Yes, you have to use field as the backing variable name in a property. The article is pretty clear about its usage.
reply
kg
51 minutes ago
[-]
Historically every time new keywords are added, they try to make them contextual so that existing code won't break. 'await' and 'yield' are both examples where a new keyword was added without (generally) breaking existing code - they're only keywords in specific contexts and the way you use them ensures that existing code won't parse ambiguously, AFAIK.
reply