C# 11 Preview Updates – Raw string literals, UTF-8 and more
devblogs.microsoft.com
devblogs.microsoft.com
[1] https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csh...
Edit - sorry c#9 seems to be available in unity now
The new features will make my C# life even easier.
The things you mention are huge, along with "UnmanagedCallersOnly", the ability to write structs and mark them as meant to be used in interop code (see "Blittable/Unmanaged Types" proposal that was recently adopted), and the seamless "DllInterop" annotations for pulling in native external methods.
https://devblogs.microsoft.com/dotnet/improvements-in-native...
https://github.com/jkoritzinsky/runtime/blob/a5048c2fe5068e9...
The team that works on the native/interop stuff is top-notch, and they're constantly pushing boundaries and making neat improvements.
I'm more of a JVM guy, but credit is well due here.
But Microsoft bad, right?
DT, Offset, and the TZInfo helpers, is better than many languages get. It's braindead simple to convert UTC to a specific TZ and to do date arithmetic.
The FAT file system (1977) stores local time, and no time zones. CDFS a.k.a. ISO 9660 (designed in 1986) was better than FAT but still less than ideal, it keeps local time, and offset in 15 minutes intervals between local time and GMT. That’s not generally convertible to UTC either.
Windows NT came with the proper file system which keeps time in UTC (also high-resolution, 100 nanoseconds versus 2 second in FAT) but most people only upgraded to NT and NTFS in 2002 with WinXP, and various external drives were still using older file systems without UTC timestamps.
.NET only dropped the support of Windows 9.x in .NET 3.0 (2006), and even afterwards they probably wanted to support all these external drives. Including timestamps of the files on these drives.
2) It’s the wrong model for representing dates and times so you end up with stuff like the midnight convention (which would be fine if it wasn’t for point 1)
In short: in 99 instances out of 100, you would be better off using DateTimeOffset, DateOnly or TimeOnly.
We need to wrap C libraries though. Does anyone have experience with or reliable benchmarks for the C interface?
.NET 7 finally also ships with NativeAOT which compiles your C# to native code that you can expose as a C library.
I benchmarked a while ago when testing this library https://github.com/Const-me/ComLightInterop#performance On the computer I was using at that time (probably Ryzen 5 3600 CPU) the overhead was 15-20 nanoseconds per call.
Nice to read about all the changes in C#, I've been thinking a lot about going back to .NET, but at this point I would probably need some training. There are things like Blazor or .NET Core that I'm absolutely unfamiliar with.
I kind of miss Visual Studio for some reason, after what feels like a lifetime of web development in other open source tech stacks.
Learn .NET Core (nowadays called just .NET). It is a fresh breeze to your memory. So easy, so rewarding compared to the complexity of Java or Node dependency trees.
How do Java dependencies differ much from C#?
Recently, I went back to C# for a smaller project. The .NET ecosystem certainly has its advantages compared to the “wild west” of NPM, which includes Visual Studio/JetBrains Rider.
My main problem was that the language feels so dated at this point. Why can’t I make local variables immutable? Why are there still no algebraic types? Why do the new nullability rules feel so inconsistent and tacked on, with “String?” and “DateTime?” behaving completely differently?
I realize not everybody cares about these “modern” features as much as I do, but once you’ve wired your brain to think about program composition in a way that simply feels better to you, it’s very frustrating to go “back”.
.
Edit: It’s not like the C# team is unaware of or in any way against these proposals. There just seems to be little visible progress:
Algebraic types: https://github.com/dotnet/csharplang/issues/113
Const locals: https://github.com/dotnet/csharplang/issues/188
How it'd work in such a case:
You declare immutable variable "a" which's an instance of a class
and then you execute "DoSomething" method which mutates under the hood?
Compilation error? runtime error?
Anyway have you tried records?
To your last question: Yes, records are really nice syntactic sugar for classes that want to behave like values.
Js has const, C has const, Java final.
Imho it'd be awesome if mutability were not the default and we would have to mark mutability, but until then any variable that doesn't need it, is final. Which also helps skimming code
C# has readonly and const
>Imho it'd be awesome if mutability were not the default
If they decided one day that - "let's make immutable by default", then it'd be performance hit - wouldn't it?
Not really. It's just a syntactic default, reassigning local variables should be discouraged from except for iterators etc. It just fosters bad habits.
For example, A list can still be mutated like usual, the reference however may not change. This usually allows compilers to do optimizations in multithreaded situations. But that's not why I code that way, it reduces the cognitive burden of keeping track which variables are actual moving parts as opposed to context/names etc.
> C# has readonly and const
Haven't written C# in a few years, GP was talking about variables as far as I can tell and their lack of immutability.
codeflo means to declare a local variable that cannot be reassigned later.
void Foo() {
// this is possible in C# today, but only for compile-time constants
const int Bar = 42;
// this is what codeflo wants: variables that cannot be changed after declaration, but can hold runtime values
readonly string text = $"Blah: {Bar + System.Environment.ProcessorCount}";
// with such a variable, you wouldn't be able to reassign it later:
text = "Some other text";
// the line above would be a compile-time error, just like trying to reassign to a readonly field.
}And can be edited without unloading the project first.
It is basically: if we introduce it, it gives us a tiny benefit for a gigantic amount of noise during every single code review. It boils down to comparing developer productivity vs. language safety.
I find the argument a bit weak since code review guidelines can end this conversation AND C# has already quite some code analysis code fixes to auto-fix language usage stuff (like file scoped namespaces or nullability checks). And that case of const and readonly can be algorithmically checked.
I suppose you can emulate it today with variable prefixes/suffixes and check the AST with a custom linter yourself
But there are other groups at Microsoft which keep them on track with their real needs.
I'm asking because I do use extensions like Roslynator for refactorings I'm not sure what I'm missing, what fancy Rider has?
Code formatting tool support was substantially better (although still not ideal) in rider than VS, and VCS backed project settings mean that we can have developers auto format locally rather than building out tooling to enforce it.
Cross platform support, with remote editing is also a huge one for me. I have a windows workstation and a Mac as a secondary workstation. Before, I had to remote into the mac and use XCode to debug/build issues on the mac, now I use rider with remote support for 95% of my mac needs, and on occasion when I do need to drop back to the mac, I'm using the same tool rather than xcode.
Until 2022 (which granted I haven't used), VS was 32 bit which despite MS's frequent assurances wasn't a problem, was. Running OOM was a regular occurance on large projects for me over the last 10 years.
I've been a happy R# customer since 2006. Since then I converted to JetBrain's all products subscription - DataGrip is a really nice database management GUI that supports nearly every database you could ever want (from SQL Server to Postgres to MongoDb!) If you do any frontend development Webstorm is IMO a much better experience than VSCode.
Since .net 6 things are changing more. Eg. The first time with a minimal API needs a bit of exploration. In general it's explained by global static functionality.
Blazer is c# and a different way of writing websites.
Asp.net MVC 4.5/webapi and before did not have IoC build-in.
I think you should reread what I said.
It wasn't there before, it is now. I didn't say anything about if it should be there.
Eg. I know an older developer who still doesn't see the benefit. So it's useful to mention that it's in there now.
I'm not spending as much time as I like coding C# nowadays but keep the R# subscription up, it's invaluable when I need to get back up and running.
- Discriminated unions
- Switch expressions as standalone statements
- Type providers, so it will verify the content of the text, provide syntax highlight, autocomplete, etc for many languages and data structures:
var sql = <SQL>"""
SELECT Id, Name FROM Users
"""- Pipe operator to avoid nested method calls (similar to F#)
What the "UTF-8 literals" feature is really about the conversion of strings to byte[] (and similar).
And more specifically the static initialisation of byte[]: initialising a byte[] from a string literal will store the UTF8 encoding of the literal as a bytes array and can be performed from static data (a bytes constant in the binary), before that you had to write the "new byte[]" with individual integral byte value by hand e.g.
byte[] thing = new byte[] { 0x77, 0x6f, 0x72, 0x6c, 0x64 };
can now be written byte[] thing = "world";This is a post about C#11 the language, not the framework or the runtime. It's only telling you about what the compiler does when it encounters some syntax. Under the hood, it probably calls some encoders from the standard library.
I write a bunch of C# for my job, but am far from an expert in the language. My reading of this statement is redundant, which means I feel sure it's trying to communicate something the authors thought was "obvious" and is not.
* A string literal - so, realistically some Unicode text, right? All the other encodings anybody was actually using can transliterate to Unicode, so, they are just Unicode (with a different encoding)
* contains only UTF-8 characters - UTF-8 is an encoding of Unicode, so, this just means Unicode again
I'm guessing actually C# can write something that's not Unicode in a String for some reason? But what that might be is unexplained:
Can you... emit arbitrary bytes? But how when your native encoding (UTF-16) isn't even byte oriented? What does that mean?
Maybe you can emit the rare Unicode "non-characters" like U+FFFF ? But, you can express those just fine in UTF-8 so who cares?
Or perhaps it's as simple as C# lets you write literals which are sequences of 16-bit code units but aren't UTF-16 ?
> The language will allow conversions between string constants and byte sequences where the text is converted into the equivalent UTF8 byte representation. Specifically the compiler will allow string_constant_to_UTF8_byte_representation_conversion - implicit conversions from string constants to byte[], Span<byte>, and ReadOnlySpan<byte>. A new bullet point will be added to the implicit conversions §10.2 section. This conversion is not a standard conversion §10.4.
byte[] array = "hello"; // new byte[] { 0x68, 0x65, 0x6c, 0x6c, 0x6f }
Span<byte> span = "dog"; // new byte[] { 0x64, 0x6f, 0x67 }
ReadOnlySpan<byte> span = "cat"; // new byte[] { 0x63, 0x61, 0x74 }
> When the input text for the conversion is a malformed UTF16 string then the language will emit an error: const string text = "hello \uD801\uD802";
byte[] bytes = text; // Error: the input string is not valid UTF16The use of whitespace to affect the meaning of strings was actually a big ask from the community and was due to a lot of confusion and frustration over the years from customers who didn't like that if they had a multiline string that it would then not indent properly with all the rest of their code and would cause things to look cluttered and unpleasant.
Users participated in the design here and we got feedback from thousands in multiple venues about this design. The behavior around whitespace here was viewed as being both very beneficial and intuitive.
Finally, to help out here, the VS ide will also draw a line showing what part of the code is content and what is not.
You feel this is overcomplicated, but this was the result of a lot of cooperative design with a lot of the user base to something that was near universally felt to be desirable over not having this behavior. :-)
>Finally, to help out here, the VS ide will also draw a line showing what part of the code is content and what is not.
This will help a lot, especially people who don't expect this behaviour. Practically answers my problem with this (when using VS at least). Still not my preferred solution, but I guess I got outvoted.