What's new in C# 12: overview
pvs-studio.com
pvs-studio.com
Having other languages be the guinea pigs for language features is a good way to go.
Java has recently left the freezer and seems to be catching up as well. I don't use Java but I see people excited about new releases since v11 or so.
Still there are plenty of markets where even .NET doesn't have a presence, like real time embedded systems, factory automation hardware, copiers, mainframes, blueray players, M2M gateways, and an OS being used by 80% of the planet, as Microsoft botched their own when it was already achieving 10% in Europe.
I love both platforms, however .NET cross-platform story still needs a bit of improvement versus where Java has been used in the last 28 years.
And DevTools eagerness to hinder it as means to sell Visual Studio licenses doesn't help.
As for Java, I guess it would be more notable that they haven't moved as much if it weren't for Kotlin.
The only feature I've been hoping for is abstract data types. I'm not sure how they could make them work in .Net though. Presumably F# has crossed that hurdle.
I get why InterceptsLocation can be useful, but why not make a more generic version that doesn't work with magic line and character offsets? Something as innocuous as a code formatter will totally break this feature. So strange.
So as it's intended for being used inside the compilation process, i don't think this is too valid of a concern.
System.Xml.Serialization, for example, relies on generating assemblies at runtime to work. That's "code generation", but of a kind that directly conflicts with the AOT meaning of "code generation".
Source generation is used at some level to implement expressivity at minimal runtime cost. It's just operating at a different level of abstraction to make different tradeoffs.
Whether you do Foo.Serialize() and it uses reflection to enumerate the properties, carries around tags permanently or it uses some compiletime generated function has nothing much to do with expressiveness.
If you design around a Foo<bar> does it matter if behind the scenes it generates a FooOfBar?
Should a language inherently care specifically about protobufs, flatbuffers, capnproto, etc because expressiveness or should it just have capable source generators for building strongly typed interfaces without the legwork? Are you sure an alternative implementation which is more expressive would be better or would it just be different?
Thinking those are the only options is exactly why the issue is expressiveness.
Likewise the new interceptors infrastructure is a workaround to avoid implementing proper AOP support, like Microsoft Fakes.
If you wanted to use a normal debugger at the same time you would usually be shown your code with the tool's generated code mixed in.
With this you could step through just your code.
Is there more information available about this? Would be great to achieve this natively without requiring Fody and friends.
Swapping out interfaces to code-gened interceptors and keeping everything else the same, doesn't look like it would improve this underlying issue at all.
You fix until tests pass. How do you know you adjusted all tests when code changes and tests stay green?
A business case can be described in code as a test. Period.
A small unit of business functionality can be described in code as test that tests that "unit". A unit test, if you will.
I don't think that the way that you're dividing out "integration tests" is a useful one.
> Wouldn’t an integration test work in that case?
Wouldn’t a test work in that case? Well, yes.
It is nuanced subject.
But say you have class A,B,C,D with mocked dependencies E,F,G,H.
There could be bugs in how A interacts with E and F that are hidden even though you have tests for A,B,C,D integrated and even unit tests on E too.
In addition, if someone comes along and refactors A,B,C,D into A',B',C',D' that have different dependencies ("Hey we are moving to microservices!") then the new integration test is different. You change test and code at the same time.
This is a problem because confidence comes from having a stable test, then changing the code and getting the green circles.
The solution (I think) is to make sure you are mocking at the level of well established boundaries. For example mock PostgreSQL. Or mock your ORM if there is a decent mock, with an in-memory version.
Then you can test end-to-end scenarios. Add a TODO, add another TODO, assert that getTodos() returns 2 results, and so on.
Instead of assert getTodos() returns 2 results when the ITodoService.getTodos() returns 2 results, and the outer getTodos just defers to it.
Then I think that parent is wrong, or rather that "it depends on what you mean by integration test" an further, this definition of "integration test" is an extremely unhelpful one that I do not advise using. And it better fits what was originally intended as "unit test". The name "unit" is not a synonym for class or method, it is your choice what the "unit" is, and a lot of the time it is best done as a small chunk of business requirement.
mocking at the level of well established boundaries such as databases and http services, is all that's needed.
And Unit tests make especially little sense in the specific service I’ve been talking about because all the logic is in the Stored Procs it calls. The service itself simply forwards that data.
You can create integration and e2e tests that aren't as sensitive but I don't really understand what people are suggesting when they say mocking is bad in unit tests.
"Unit test" does not necessarily mean "class test" or "method test"
and always treating it as such is counterproductive.
I have done it both ways. tests coupled to every public method with dozens of mocks would not be my preference.
It is irrelevant and driven by some testing evangelists
Tests are either quick or slow and may touch external stuff, thats mostly it.
Whats wrong with mocks? If they lead to scenarios where your tests are green, but app doesnt work then it sucks. Ive witnessed projects with all green tests but app wasnt even waking.
I'd rather spend time trying to learn the business, and where it's going, and why my product is useful, than mocking out some dumb part I can test a few times manually. Unit tests are super valuable tool, but not everything needs a unit test.
At work, I have better things to do than waste time on this for PR, so I create those interfaces, thankfully there are VS tools to create them automatically.
The reason this is so common is probably because code examples (including MS) often have it, so it gets followed the first time and repeated.
There is PolySharp project that enables you to use most of C#11 features in legacy .NET Framework: https://github.com/Sergio0694/PolySharp - Seems that C#12 features are planned to be implemented: https://github.com/Sergio0694/PolySharp/issues/78
I'm using PolySharp where I'm stuck with .NET Framework 4.6 and I don't have any issues.
Hope one day I'd see concise syntax for catch and/or try expressions: https://github.com/dotnet/csharplang/discussions/2734 - but there is a lot of resistance.
A C# developers who went into coma in 2012 after learning about async/await and ASP.NET MVC can be awakened today and be instantly productive. Although he might go into coma again if he finds out .Net is now open source, cross-platform, and that we deploy to "Linux containers".
Like you say Visual Studio helps a lot with suggesting improvements, and of course all my old ways are still valid.
I think with target typed new and this new collection syntax I probably won't use var anymore.
If you want to write out Dictionary<Guid, ILookup<int, List<MyEntity>>> instead of having it inferred then go for it I guess.
That line and character worries me
But since this is generated then maybe it is fine?
https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...
There was a plan to have "natural type" so "var list = [1,2,3]" would be of type "List<int>" but it was postponed to C# 13 (https://github.com/dotnet/csharplang/issues/5354#issuecommen...)
class Point {
public Point(this x, this y);
int x;
int y
}
Everything else seems like small quality of life improvements.And still patiently waiting for the following to be legal:
int result = some_variable switch { a => callAFunctionReturningVoid(); 1, b => 2, };What does it even mean? Multi-statement lambdas without return statement, I get it, but what is the return value? And returning a void to int? How is it all supposed to work? What the trailing comma means? Inconsistent way of dealing with things that may confuse developers just results in that proposal resisted.
> The expression is the body of the function, the last expression of which generates a return value. Examples of valid lambda expressions include the following:
https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...
They don't have generic support no ? You create tuple type for every method ?
(bool HasFailed, string Status)
Also yes tuples do support generics.I feel that recent "features" are more in the "things I can do with a preprocessor or a code generator" than real language enhancements.
Of course, I can be (and I'm probably) extremely wrong, but I find that release pace exhausting and I see a lot of great software written without resorting to new "features".
Well, you can hack a lot with code gen, but thats not the way, imo.
But using your logic: are generics a feature? Since you could achieve almost identical results with code gen hacks
We have generics since .NET 2 (2005 IIRC) and at the time, the lang improvements had a reason to exist (framework support in some cases). At the time it was a nice thing to add, if you ask me. For me, the next big thing, if you ask, was LINQ.
A few years later, I feel it's not the case with recent additions. But my comment is very subjective, of course.
As I said, I can be very wrong. It's just that I find he lang "very complete", if that's a thing, since a few years.
Extension methods are lang feature, LINQ is implemented with ext. Methods.
You can argue that there is LINQ Query syntax instead of method chaining, but almost nobody is using this except for some specific cases (let keyword)
But I thought they are implemented at library level, but now Im not sure
As someone that has spent far too much time in JS world any time I’m able to ditch a preprocessor or code generator is a a great relief. I want my build processes to be as simple and straightforward as they can possibly be.
https://learn.microsoft.com/en-us/dotnet/csharp/advanced-top...
The only C# generator I'm familiar with is for protobuf. I suppose the P/Invoke generators count too.
I know, I already did that (generating mapping to industrial controllers from the config).
> The only C# generator I'm familiar with is for protobuf.
If you use .NET 6 you may use multiple source generator without knowing, it's very transparent.
For example, if you use System.Text.Json you may be using code generation.
Why would we need to make a struct with an attribute and a weird member?
It seems to me the budget for C# lang dev is way down. This seems like it was implemented this way so they didn't have to change many internals.