MarimerLLC / csla

A home for your business logic in any .NET application.
https://cslanet.com
MIT License
1.27k stars 406 forks source link

Consider whether lists can be initialized to empty instead of null #4266

Open rockfordlhotka opened 1 month ago

rockfordlhotka commented 1 month ago
          > > Another question: Any good reason why this lists can't just be initialized and hence empty if not neede and/or used? Makes the nullable stuff a lot easier and even more intuitive to use. Currently accessing `DirtyProperties` in a rule would return `null` instead of an empty list...

https://github.com/MarimerLLC/csla/blob/aa14c3f86e3052d73cb06785b6fb6c381e6eb9f2/Source/Csla/Rules/RuleContext.cs#L84-L98

https://github.com/MarimerLLC/csla/blob/aa14c3f86e3052d73cb06785b6fb6c381e6eb9f2/Source/Csla/Rules/RuleContext.cs#L66-L82

CSLA often doesn't initialize lists of types that might be serialized, because it is much smaller to serialize null than it is to serialize an empty list. This is because the serializer doesn't need to flow the list's type information for null, but it does need to flow the type information for an empty list so the empty list can be deserialized on the other end of the process.

For MobileFormatter, yes, you need to serialize type information for a collection type so you know what to create on the other side. But that isn't a strict requirement for CSLA serialization. For example, my source generator serializer doesn't require this, because it knows at compile-time what the underlying type is for the field, and can new it up how it sees fit. For collections like List<T>, I don't special-case that one, but it's trivial to add a custom implementation for that in my generator through configuration.

Also, I do like empty collections over null in general overall. Then I don't need to wonder, "is this a null list or not?" everywhere in my code. If the performance implications of a null list over an empty one is significant during serialization, then....maybe keep them null, but if it's essentially negligible, then I'd much rather see an empty list.

Originally posted by @JasonBock in https://github.com/MarimerLLC/csla/issues/1233#issuecomment-2429212811

StefanOssendorf commented 1 month ago

I agree. I find it really weird to have a list null instead of just empty. What exactly is the difference in use? If we want to keep/improve (de)serialization speed, we can special-case empty lists etc. so null is transported and we just re-initialize it on the other side.

JasonBock commented 1 month ago

That's a good point. If a list is empty, serialize null, and then deserialize to an empty list.

I would really like to see perf data (using something like Benchmark.NET) to see what the perf benefit is to using null for serialization over an empty list. My guess is that it's negligible and doesn't outweigh the benefits of being able to reason about you code without worrying about null values. But the only way to know for sure is to measure and get numbers :)

rockfordlhotka commented 1 month ago

Null and empty aren't the same thing, so I don’t think we can translate arbitrarily. I kind of suspect that would affect lazy loading, though that'll require some exploration.

It isn't the perfect of serialization that's in question, it is the size of the payload. And that may be incidental, so metrics need to be established.