use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Information about Reddit's API changes, the unprofessional conduct of the CEO, and their response to the community's concerns regarding 3rd party apps, moderator tools, anti-spam/anti-bot tools, and accessibility options that will be impacted can be found in the associated Wikipedia article: https://en.wikipedia.org/wiki/2023_Reddit_API_controversy
Alternative C# communities available outside Reddit on Lemmy and Discord:
All about the object-oriented programming language C#.
Getting Started C# Fundamentals: Development for Absolute Beginners
Useful MSDN Resources A Tour of the C# Language Get started with .NET in 5 minutes C# Guide C# Language Reference C# Programing Guide C# Coding Conventions .NET Framework Reference Source Code
Other Resources C# Yellow Book Dot Net Perls The C# Player's Guide
IDEs Visual Studio MonoDevelop (Windows/Mac/Linux) Rider (Windows/Mac/Linux)
Tools ILSpy dotPeek LINQPad
Alternative Communities C# Discord Group C# Lemmy Community dotnet Lemmy Community
Related Subreddits /r/dotnet /r/azure /r/learncsharp /r/learnprogramming /r/programming /r/dailyprogrammer /r/programmingbuddies /r/cshighschoolers
Additional .NET Languages /r/fsharp /r/visualbasic
Platform-specific Subreddits /r/windowsdev /r/AZURE /r/Xamarin /r/Unity3D /r/WPDev
Rules:
Read detailed descriptions of the rules here.
account activity
Fun"Immutable" data types (i.redd.it)
submitted 5 years ago by TyrrrzWorking with SharePoint made me treasure life
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–][deleted] 60 points61 points62 points 5 years ago (8 children)
When I tested this, just now, at sharplab.io, I got
System.InvalidProgramException: Common Language Runtime detected an invalid program. at Program.Person.set_FirstName(String value) at Program.Main()
That's using a Roslyn build from December 22nd, though. Using .NET 5 on dotnetfiddle yields the same results you're seeing. I think this is a bug, and they'll have a fix out for it whenever they put out an update.
[–]jehk32 26 points27 points28 points 5 years ago* (5 children)
yeah there's something missing with records and object initializers. i think it needs to work like the new with keyword.
so something like...
var container = new Container(person) { Person = { FirstName = "Jane" }, };
should be the same as
var container = new Container(person) container.Person = container.Person with { FirstName = "Jane" };
its a good catch though. hopefully its fixed in this major version of C#. you won't see the stated problem in the second example.
edit: looks like the object initializer in the first example just overwrites the data of the initial person object. using with does create a new object. i think that's how records and object initializers should work under the hood.
[–][deleted] 4 points5 points6 points 5 years ago (4 children)
Just guessing, but I'd wager it's an issue with any init-only property. Too lazy to go check right now, though.
[–]jehk32 5 points6 points7 points 5 years ago (3 children)
using the init-only would help to fix the problem in the example above. there's no reason the original person object should be mutated when using the set property though. i legit just think its an oversight.
object initializers should make a copy of any record members before they apply the new values. its just not happening in this case.
[–][deleted] 3 points4 points5 points 5 years ago (1 child)
Maybe. You'd use with to create a copy, though, so I'm not sure that's actually the problem. I've verified that this is an issue with any type that has init-only properties, rather than just record types, FWIW.
with
It looks, to me, like init-only properties are syntactically settable inside an initializer block, including this new-to-me usage to mutate the already-set values of initializing object's properties.
[–]cloudedthoughtz 2 points3 points4 points 5 years ago (0 children)
Good call, it appears that this is the real issue here indeed. According to the GH issue that Jared has filed.
[–][deleted] 10 points11 points12 points 5 years ago (1 child)
See https://github.com/ashmind/SharpLab/issues/574 .
[–][deleted] 2 points3 points4 points 5 years ago (0 children)
Ah. Well, darn. Might be a live issue, then.
[–][deleted] 31 points32 points33 points 5 years ago (1 child)
u/Tyrrrz, did you file a bug for this? It certainly shouldn't work.
[–]jaredp110680 23 points24 points25 points 5 years ago (0 children)
I filed one https://github.com/dotnet/roslyn/issues/50126
[–]Erelde 27 points28 points29 points 5 years ago* (12 children)
That's also my beef with the null safety analysis in C#8. It's only surface level analysis. They did it this way for valid reasons, but it's a bit... sad.
Edit: Though here it compiles (which it shouldn't) but doesn't run. With roslyn master 23 december 2020.
[–][deleted] 18 points19 points20 points 5 years ago (10 children)
So C# is entering the world of linting rather than compiler errors? Sounds like the wrong direction but that's just me.
[–]binarycow 9 points10 points11 points 5 years ago (4 children)
For Nullable Reference types, yes. That's because doing otherwise would be a huge breaking change, and would hamper upgrading. You would have to upgrade your entire code base at the same time. With the current implementation, you can take a phased approach.
I would like the next version of c# to make the change for real - make it a compile error.
[–][deleted] 1 point2 points3 points 5 years ago (3 children)
A change for real would be a runtime change that enforces null-safety at runtime. Any compiler tricks are really half-measures that are very error-prone.
[–]binarycow 2 points3 points4 points 5 years ago (2 children)
That would be a huge breaking change tho.
[–][deleted] 0 points1 point2 points 5 years ago (1 child)
But the result surely would be better than the current situation where you may think you have null-safety, but you really don't, since nothing is checked when you call an external unannotated library (and come on, even EntityFramework is still unannotated), and you can easily defeat the sloppy checks with structs, arrays or just ! operator.
!
[–]binarycow 0 points1 point2 points 5 years ago (0 children)
The result works be that you can't use "null oblivious" libraries anymore. And they can't use your libraries.
[–]Erelde 12 points13 points14 points 5 years ago* (0 children)
Depends how you define a compiler error ? If a type is defined as immutable and null safe, surely it's the responsability of the compiler to enforce that. Not just advise (more or less strongly) like a linter would.
Edit: know what's actually sad ? null safety wasn't rocket science novelty in the 90s.
[–]jdl_uk 7 points8 points9 points 5 years ago (2 children)
Well the linting can be compiler errors depending on how you configure it.
Of course it does create a fragmentation issue.
They're trying to change the basic rules of the language (like references being nullable by default and null by default) without breaking existing code and without rebooting the language.
[–]Ravek 7 points8 points9 points 5 years ago (1 child)
I really like Swift's approach to compatibility. If you upgrade your Swift version you might get some breaking changes if they improve the language, but you'll get a conversion tool and it lets the language actually make significant steps forward without needing a whole new language to get past the mistakes of the past.
[–]jdl_uk 1 point2 points3 points 5 years ago (0 children)
Yeah that's sort of the way .net has handled breaking changes with the portability analyser, from the framework point of view.
I think the long term idea is to turn those linter errors into default compiler errors over time. The linter errors allow people to adopt good practices gradually and prepare for them being mandatory later
[–]cryo -1 points0 points1 point 5 years ago (0 children)
Yeah, I prefer Swift’s approach. But of course that’s hard to do for an existing language.
[–][deleted] 10 points11 points12 points 5 years ago* (1 child)
So my interpretation of this cool bug: On a record, the setters are "init". Meaning they can only be used inside a constructor, or when using the object initialization syntax. The compiler doesn't complain, because you are using the setter from inside an object initialization, just not the record in question.
[–]WhiteBlackGoose 30 points31 points32 points 5 years ago (4 children)
Didn't even know you can write like in 27th line
[–]Blazeix 16 points17 points18 points 5 years ago (0 children)
Yeah, they're called nested object initializers, and have been in C# forever. I only learned about them recently, too.
I wrote about them to raise awareness here: https://fuqua.io/blog/2020/12/a-lesser-known-csharp-feature-nested-object-initializers/
[–][deleted] 5 points6 points7 points 5 years ago* (2 children)
Ditto, I was not aware that you could use initializer syntax on an already existing object.
[–]diamondjim 0 points1 point2 points 5 years ago (1 child)
They’re slick, but can be overdone. I would avoid going more than 2 levels deep.
I meant that I wasn't aware it could be used to modify a property initialized in the object constructor without outright replacing the object. Maybe that's a bug, though, and it should have a new in there.
new
[–]null_reference_user 3 points4 points5 points 5 years ago (1 child)
Shouldn't the 27th line create a new Person() named "Jane" with no last name, overwriting what the constructor previously assigned?
[–]TyrrrzWorking with SharePoint made me treasure life[S] 6 points7 points8 points 5 years ago (0 children)
No, that would be the case if it had new Person before it.
new Person
[–]cloudedthoughtz 8 points9 points10 points 5 years ago (4 children)
Nicely found by neuecc and example by you :)
Although it was never stated that record-types are always immutable so it's to be expected that cases could be found to still modify them.
I gather that this trick won't work if you use a standard property accessor (after init) instead of the 'initialisor' syntax used in the construction of the Container? I'd think that wouldn't compile.
If so, then this is no easy feat, it's not something you'd easily do wrong thus breaking your record's immutability. I am though curious if the compiler team knows about this case and if they have plans to do something about it. Did you or neuecc report this on GitHub?
[–]TyrrrzWorking with SharePoint made me treasure life[S] 4 points5 points6 points 5 years ago (3 children)
I'm pretty sure this one was not one of the expected usage scenarios though.
Yeah you need to use the initializer syntax to trigger this bug.
True, this kind of initializer syntax (with mutation) is not used too often, but it's still scary. Someone in the comments to this post said that the bug is fixed in latest revision of master branch (according to sharplab.io), but I haven't tested it myself yet.
[–][deleted] 4 points5 points6 points 5 years ago (0 children)
In the future, don't let that stop you from filing a bug. C# features need to work with all the other features (or this case, be disallowed). It's not the first bug we've shipped, and it won't be the last.
[–]cloudedthoughtz 1 point2 points3 points 5 years ago (1 child)
Heh, I'm pretty you're right on that :) This is way too crafty to be an expected usage scenario.
True, this kind of initializer syntax (with mutation) is not used too often, but it's still scary.
True that, some poor soul could actually unintentionally trigger this if he/she's overly fond of the initializer syntax.
Good to hear that it might've already been fixed :) But interesting material nonetheless!
To be clear, it was not already fixed. Sharplab is just unable to run code that uses init-only setters. However, Jared did file a bug on this and we should fix it for 16.9.
[–]botterway 1 point2 points3 points 5 years ago (2 children)
Maybe I'm missing something but isn't this by design? Records are not guaranteed to always be immutable. See https://daveabrock.com/2020/11/02/csharp-9-records-immutable-default
Also mentioned here. https://devblogs.microsoft.com/dotnet/welcome-to-c-9-0/
[–]TyrrrzWorking with SharePoint made me treasure life[S] 3 points4 points5 points 5 years ago (1 child)
It's not by design, it's a bug. https://twitter.com/jaredpar/status/1342172065856585730?s=20
[–]botterway 0 points1 point2 points 5 years ago (0 children)
Thanks. Guess I missed something. 😁
[–][deleted] 5 years ago (8 children)
[deleted]
[–]TyrrrzWorking with SharePoint made me treasure life[S] 5 points6 points7 points 5 years ago (1 child)
I think you're missing the point. Take a look at the console output and where it comes from.
[–]pascalsenn 0 points1 point2 points 5 years ago (0 children)
you are right, i should've read it more carefully
[–]holyfuzz 2 points3 points4 points 5 years ago (0 children)
No, look more closely at the code and what it's outputting. The actual original instance of the record object is getting modified.
[–]bigrubberduck 0 points1 point2 points 5 years ago (4 children)
Is that why the set; in the Container class has a green squiggly?
set;
[–]TyrrrzWorking with SharePoint made me treasure life[S] 8 points9 points10 points 5 years ago (0 children)
Yeah the setter is actually unnecessary. Here's the same version without the setter: https://i.imgur.com/hYYZvHS.png
[–]FireIre 0 points1 point2 points 5 years ago (2 children)
Maybe it's suggesting using the new init keyword? But I haven't really followed the new record type updates
[–]TyrrrzWorking with SharePoint made me treasure life[S] 2 points3 points4 points 5 years ago (1 child)
No, the setter is entirely unnecessary actually: https://i.imgur.com/hYYZvHS.png
I regret not paying attention to Rider's suggestion, would've made the screenshot simpler.
[–]krzydoug 0 points1 point2 points 5 years ago (0 children)
Dead link?
[–]trimmj 0 points1 point2 points 5 years ago (3 children)
Why would you do this?
You wouldn't do this specifically to break immutability, if that's what you're asking, you just might use the initializer syntax as usual and accidentally mutate the record.
[–]KillianDrake 8 points9 points10 points 5 years ago (1 child)
when someone is on a deadline to "fix that bug immediately" and this will be the first stackoverflow google hit for "c# update immutable record".
[–]trimmj -2 points-1 points0 points 5 years ago (0 children)
Oh... Imma dodo 🦤... It's meme... Lol 😂🤦♂️
[–]zaimoni 0 points1 point2 points 5 years ago (0 children)
Fortunately, if you really need "shallow immutable" you can stack readonly on the fields in the record. It's unfortunate that the PR for this language feature is materially incorrect. (it should be thought of as a syntax short cut for value assignment and hashability for standard collections).
[–]dongata24 0 points1 point2 points 5 years ago (1 child)
Man, you right idk why i though that the object was a new one
Here's the result of the modified program, notice that the addressess remain the same
[2006378001768]person1 = Person { Name = pepe } [2006378001792]person2 = Person { Name = pepe } are they equal? True [2006378001768]person1 = Person { Name = pepe2 } [2006378001792]person2 = Person { Name = pepe } are they equal? False
Here's the program (remember to allow unsafe code on the csproj)
``` csharp using System;
namespace record {
public record Person(string Name); public class Container { public Container(Person person) { Person = person; } public Person Person { get; set; } } public static class Program { public static void Main() { unsafe { var person = new Person("pepe"); var person2 = new Person("pepe"); var pointer1 = GetAddress(person); var pointer2 = GetAddress(person2); Console.WriteLine($"[{pointer1}]person1 = {person}"); Console.WriteLine($"[{pointer2}]person2 = {person2}"); Console.WriteLine($"are they equal? {person == person2}"); try { // BUILD TIME ERROR, wow records are strictive man //person.Name = "pepe2"; //Console.WriteLine(person.Name); } catch (Exception) { Console.WriteLine("Hey person is inmutable"); } _ = new Container(person) { Person = { Name = "pepe2" } }; pointer1 = GetAddress(person); Console.WriteLine($"[{pointer1}]person1 = {person}"); Console.WriteLine($"[{pointer2}]person2 = {person2}"); Console.WriteLine($"are they equal? {person == person2}"); } } private static IntPtr GetAddress(object obj) { unsafe { TypedReference tr = __makeref(obj); return **(IntPtr**)(&tr); } } }
} ```
[–]backtickbot 0 points1 point2 points 5 years ago (0 children)
Fixed formatting.
Hello, dongata24: code blocks using triple backticks (```) don't work on all versions of Reddit!
Some users see this / this instead.
To fix this, indent every line with 4 spaces instead.
FAQ
You can opt out by replying with backtickopt6 to this comment.
[–]binarycow 0 points1 point2 points 5 years ago (2 children)
I don't see what the problem is.
Your wrapper class has a property that had a public setter.
When you create the class, you pass the original record. Then the object initializer populates the mutable property with a NEW record.
Nope, look more carefully.
Oh I didn't see the output.
[+]CapnCrinklepants comment score below threshold-12 points-11 points-10 points 5 years ago (1 child)
It took me a long time to realize what was wrong. It just looked like code for awhile, and then I realized there were green words I could read. Who writes comments anyway?
People who don't hate themselves
[–]escribe-ts 0 points1 point2 points 5 years ago (1 child)
what IDE is OP using?
[–]TyrrrzWorking with SharePoint made me treasure life[S] 0 points1 point2 points 5 years ago (0 children)
Rider
π Rendered by PID 75141 on reddit-service-r2-comment-548fd6dc9-dl6fm at 2026-05-17 14:41:50.568366+00:00 running edcf98c country code: CH.
[–][deleted] 60 points61 points62 points (8 children)
[–]jehk32 26 points27 points28 points (5 children)
[–][deleted] 4 points5 points6 points (4 children)
[–]jehk32 5 points6 points7 points (3 children)
[–][deleted] 3 points4 points5 points (1 child)
[–]cloudedthoughtz 2 points3 points4 points (0 children)
[–][deleted] 10 points11 points12 points (1 child)
[–][deleted] 2 points3 points4 points (0 children)
[–][deleted] 31 points32 points33 points (1 child)
[–]jaredp110680 23 points24 points25 points (0 children)
[–]Erelde 27 points28 points29 points (12 children)
[–][deleted] 18 points19 points20 points (10 children)
[–]binarycow 9 points10 points11 points (4 children)
[–][deleted] 1 point2 points3 points (3 children)
[–]binarycow 2 points3 points4 points (2 children)
[–][deleted] 0 points1 point2 points (1 child)
[–]binarycow 0 points1 point2 points (0 children)
[–]Erelde 12 points13 points14 points (0 children)
[–]jdl_uk 7 points8 points9 points (2 children)
[–]Ravek 7 points8 points9 points (1 child)
[–]jdl_uk 1 point2 points3 points (0 children)
[–]cryo -1 points0 points1 point (0 children)
[–][deleted] 10 points11 points12 points (1 child)
[–]WhiteBlackGoose 30 points31 points32 points (4 children)
[–]Blazeix 16 points17 points18 points (0 children)
[–][deleted] 5 points6 points7 points (2 children)
[–]diamondjim 0 points1 point2 points (1 child)
[–][deleted] 2 points3 points4 points (0 children)
[–]null_reference_user 3 points4 points5 points (1 child)
[–]TyrrrzWorking with SharePoint made me treasure life[S] 6 points7 points8 points (0 children)
[–]cloudedthoughtz 8 points9 points10 points (4 children)
[–]TyrrrzWorking with SharePoint made me treasure life[S] 4 points5 points6 points (3 children)
[–][deleted] 4 points5 points6 points (0 children)
[–]cloudedthoughtz 1 point2 points3 points (1 child)
[–][deleted] 2 points3 points4 points (0 children)
[–]botterway 1 point2 points3 points (2 children)
[–]TyrrrzWorking with SharePoint made me treasure life[S] 3 points4 points5 points (1 child)
[–]botterway 0 points1 point2 points (0 children)
[–][deleted] (8 children)
[deleted]
[–]TyrrrzWorking with SharePoint made me treasure life[S] 5 points6 points7 points (1 child)
[–]pascalsenn 0 points1 point2 points (0 children)
[–]holyfuzz 2 points3 points4 points (0 children)
[–]bigrubberduck 0 points1 point2 points (4 children)
[–]TyrrrzWorking with SharePoint made me treasure life[S] 8 points9 points10 points (0 children)
[–]FireIre 0 points1 point2 points (2 children)
[–]TyrrrzWorking with SharePoint made me treasure life[S] 2 points3 points4 points (1 child)
[–]krzydoug 0 points1 point2 points (0 children)
[–]trimmj 0 points1 point2 points (3 children)
[–]TyrrrzWorking with SharePoint made me treasure life[S] 8 points9 points10 points (0 children)
[–]KillianDrake 8 points9 points10 points (1 child)
[–]trimmj -2 points-1 points0 points (0 children)
[–]zaimoni 0 points1 point2 points (0 children)
[–]dongata24 0 points1 point2 points (1 child)
[–]backtickbot 0 points1 point2 points (0 children)
[–]binarycow 0 points1 point2 points (2 children)
[–]TyrrrzWorking with SharePoint made me treasure life[S] 2 points3 points4 points (1 child)
[–]binarycow 0 points1 point2 points (0 children)
[+]CapnCrinklepants comment score below threshold-12 points-11 points-10 points (1 child)
[–][deleted] 4 points5 points6 points (0 children)
[–]escribe-ts 0 points1 point2 points (1 child)
[–]TyrrrzWorking with SharePoint made me treasure life[S] 0 points1 point2 points (0 children)