From 117c4d7ae329d88e3781b3a4b3f26f01d8646ec9 Mon Sep 17 00:00:00 2001 From: Sefer Mirza Date: Tue, 3 Mar 2026 10:12:09 +0300 Subject: [PATCH 01/29] init 'issue/dotnet-10/research' --- dotnet-10-research-notes.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 dotnet-10-research-notes.md diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md new file mode 100644 index 0000000..04c7210 --- /dev/null +++ b/dotnet-10-research-notes.md @@ -0,0 +1 @@ +# .NET 10 Research Notes \ No newline at end of file From 6da5872f2ad6051a3c582fee85cca03e5626ecb3 Mon Sep 17 00:00:00 2001 From: Sefer Mirza Date: Tue, 3 Mar 2026 13:09:23 +0300 Subject: [PATCH 02/29] add research notes --- dotnet-10-research-notes.md | 65 ++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md index 04c7210..c287b79 100644 --- a/dotnet-10-research-notes.md +++ b/dotnet-10-research-notes.md @@ -1 +1,64 @@ -# .NET 10 Research Notes \ No newline at end of file +# .NET 10 Research Notes + +## Runtime + +[Runtime'daki değişiklikler](https://learn.microsoft.com/tr-tr/dotnet/core/whats-new/dotnet-10/runtime) +doğrudan uygulanıyor. + +## Libraries + +### Numeric ordering for string comparison + +stringlerin sonuna göre sıralama yapıyor. + +```csharp +foreach (string os in new[] { "Windows 11", "Windows 10", "Windows 8" }.Order(numericStringComparer)) +{ + Console.WriteLine(os); +} + +// Output: +// Windows 8 +// Windows 10 +// Windows 11 +``` + +### Serialization + +Bir kaç işimize yarayabilecek serileştirme güncellemesi var ama biz Newtonsoft +kullanıyoruz. + +https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/libraries#serialization + +## SDK + +### Support for Microsoft Testing Platform in dotnet test + +dotnet test natively supports Microsoft.Testing.Platform. To enable this +feature, add the following configuration to your global.json file: + +```csharp +{ + "test": { + "runner": "Microsoft.Testing.Platform" + } +} +``` + +[MTP](https://learn.microsoft.com/en-us/dotnet/core/testing/microsoft-testing-platform-intro) + +## ASP.NET + +### Treating empty string in form post as null for nullable value types + +When using the [FromForm] attribute +```csharp +app.MapPost("/todo", ([FromForm] Todo todo) => TypedResults.Ok(todo)); + +... + +public class Todo +{ + public DateOnly? DueDate { get; set; } // Empty strings map to `null` +} +``` \ No newline at end of file From 90575c905349ccd946113b0738da5a0319a7f327 Mon Sep 17 00:00:00 2001 From: Sefer Mirza Date: Tue, 3 Mar 2026 19:14:18 +0300 Subject: [PATCH 03/29] add more research notes --- dotnet-10-research-notes.md | 102 +++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md index c287b79..0d54125 100644 --- a/dotnet-10-research-notes.md +++ b/dotnet-10-research-notes.md @@ -61,4 +61,104 @@ public class Todo { public DateOnly? DueDate { get; set; } // Empty strings map to `null` } -``` \ No newline at end of file +``` + +### Validation support in Minimal APIs + +`AddValidation` ile response model'de eklenen attributes'lar ile validasyon yapılabiliyor + +```csharp +app.MapPost("/products", + ([EvenNumber(ErrorMessage = "Product ID must be even")] int productId, [Required] string name) + => TypedResults.Ok(productId)) + .DisableValidation(); +//****** +public record Product( + [Required] string Name, + [Range(1, 1000)] int Quantity); +``` + +### `IProblemDetailsService` + +Defines a type that provide functionality to create a ProblemDetails response. + +Bu 7'den sonra da varmış. Kullanmamışız. Ben yinede ekliyim belki şimdi bazı şeyleri kolaylayabilir. + +https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.iproblemdetailsservice?view=aspnetcore-10.0 + +### Validation APIs moved to `Microsoft.Extensions.Validation` + +The validation APIs have moved to the `Microsoft.Extensions.Validation` +namespace and NuGet package. + +### OpenAPI + +#### Response description on ProducesResponseType for API controllers + +The `ProducesAttribute`, `ProducesResponseTypeAttribute`, and +`ProducesDefaultResponseTypeAttribute` now accept an optional string parameter, +`Description`, that sets the description of the response: + +```C# +[HttpGet(Name = "GetWeatherForecast")] +[ProducesResponseType>(StatusCodes.Status200OK, + Description = "The weather forecast for the next 5 days.")] +public IEnumerable Get() +{ +``` + +#### Support for `IOpenApiDocumentProvider` in the DI container + +bu servis OpenAPI dokümanını kod içinden programatik olarak alabilmeyi sağlıyor + +#### Use HTTP Method Object Instead of Enum + +```csharp +// Before (1.6) +OpenApiOperation operation = new OpenApiOperation +{ + HttpMethod = OperationType.Get +}; + +// After (2.0) +OpenApiOperation operation = new OpenApiOperation +{ + HttpMethod = new HttpMethod("GET") // or HttpMethod.Get +}; +``` + +[daha fazla 2.0 değişikliği için](https://github.com/microsoft/OpenAPI.NET/blob/main/docs/upgrade-guide-2.md) + +### Authenticatio and authorization + +#### Avoid cookie login redirects for known API endpoints + +sanırım bu bizi ilgilendirmiyor biz login e redirect etmiyoruz zaten ama yapılan +şeyi yinede yazayım: +Artık bilinen API endpoint'lerine yapılan yetkisiz istekler login sayfasına +yönlendirme yerine doğrudan 401 ve 403 döndürüyor. + +### Diğerleri + +#### Support for the .localhost Top-Level Domain + +```json +{ + "profiles": { + "https": { + "applicationUrl": "https://myapp.dev.localhost:7099;http://myapp.dev.localhost:5036" + } + } +} +``` + +> [!NOTE] +> +> After installing .NET 10 SDK Preview 7, trust the new developer certificate by +> running dotnet dev-certs https --trust at the command line to ensure your +> system is configured to trust the new certificate. + +#### Detect if URL is local using `RedirectHttpResult.IsLocalUrl` + +`RedirectHttpResult.IsLocalUrl` diye bir helper gelmiş. url veriyorsun oradaki +redirecturl locale e mi gidecek diye bakıyor. locale se true dönüyor. \ No newline at end of file From 775297209d2aa45bc2541f4aa9004254fff4eb9a Mon Sep 17 00:00:00 2001 From: Sefer Mirza Date: Tue, 3 Mar 2026 19:51:51 +0300 Subject: [PATCH 04/29] add last update notes --- dotnet-10-research-notes.md | 99 ++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md index 0d54125..ee9a985 100644 --- a/dotnet-10-research-notes.md +++ b/dotnet-10-research-notes.md @@ -161,4 +161,101 @@ yönlendirme yerine doğrudan 401 ve 403 döndürüyor. #### Detect if URL is local using `RedirectHttpResult.IsLocalUrl` `RedirectHttpResult.IsLocalUrl` diye bir helper gelmiş. url veriyorsun oradaki -redirecturl locale e mi gidecek diye bakıyor. locale se true dönüyor. \ No newline at end of file +redirecturl locale e mi gidecek diye bakıyor. locale se true dönüyor. + +## C# 14 + +### Extension members + +yeni extension yazma yöntemleri geldi + +```csharp +public static class Enumerable +{ + // Extension block + extension(IEnumerable source) // extension members for IEnumerable + { + // Extension property: + public bool IsEmpty => !source.Any(); + + // Extension method: + public IEnumerable Where(Func predicate) { ... } + } + + // extension block, with a receiver type only + extension(IEnumerable) // static extension members for IEnumerable + { + // static extension method: + public static IEnumerable Combine(IEnumerable first, IEnumerable second) { ... } + + // static extension property: + public static IEnumerable Identity => Enumerable.Empty(); + + // static user defined operator: + public static IEnumerable operator + (IEnumerable left, IEnumerable right) => left.Concat(right); + } +} +``` + +### `field` + +artık field tanımlamaya gerek yok + +```csharp +public string Name +{ + get; + set => field = value ?? throw new ArgumentNullException(nameof(value)); +} +``` + +### Implicit Span Conversions + +Span ve ReadOnlySpan için, ReadOnlySpan, Span ve T[] türlerine +implicit cast gelmiş + +```csharp +int[] array = new[] { 1, 2, 3 }; +ReadOnlySpan ros = array; + +void Process(ReadOnlySpan data) { } +Process(array); +``` + +### `nameof` Unbound Generic Types + +aşağıdaki işlemlere izin veriliyormuş + +```csharp +nameof(List<>) +nameof(Dictionary<,>) +``` + +### Simple lambda parameters with modifiers + +scoped, ref, in, out, or ref readonly gibi lambda expression parametrelerinde +type belirtme biraz daha hafiflemiş. bunlarda analyzerlar önerileri veriyor zaten + +```csharp +TryParse parse2 = (string text, out int result) => Int32.TryParse(text, out result); +``` + +### partial members + +artık instance constructors ve events partial olabiliyormuş + +### User-Defined Compound Assignment + +sanırım eskiden +=, -=, *= gibi operatorleri kendin yazamıyordun. artık +yazılabiliyor gibi + +tam olarak hangilerine izin var tam anlamadım https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-14.0/user-defined-compound-assignment +### Null-Conditional Assignment + +atamalarda if ile not null kontrolüne gerek kalmamış + +```csharp +customer?.Order = GetCurrentOrder(); +``` + +ama +=, -= falan desteklemiyor \ No newline at end of file From d227384e045d040759021e5d2859dbc4312d8d06 Mon Sep 17 00:00:00 2001 From: Sefer Mirza Date: Tue, 3 Mar 2026 21:00:39 +0300 Subject: [PATCH 05/29] add new task --- dotnet-10-research-notes.md | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md index ee9a985..fa5b60a 100644 --- a/dotnet-10-research-notes.md +++ b/dotnet-10-research-notes.md @@ -1,10 +1,5 @@ # .NET 10 Research Notes -## Runtime - -[Runtime'daki değişiklikler](https://learn.microsoft.com/tr-tr/dotnet/core/whats-new/dotnet-10/runtime) -doğrudan uygulanıyor. - ## Libraries ### Numeric ordering for string comparison @@ -12,6 +7,8 @@ doğrudan uygulanıyor. stringlerin sonuna göre sıralama yapıyor. ```csharp +StringComparer numericStringComparer = StringComparer.Create(CultureInfo.CurrentCulture, CompareOptions.NumericOrdering); + foreach (string os in new[] { "Windows 11", "Windows 10", "Windows 8" }.Order(numericStringComparer)) { Console.WriteLine(os); @@ -23,14 +20,14 @@ foreach (string os in new[] { "Windows 11", "Windows 10", "Windows 8" }.Order(nu // Windows 11 ``` -### Serialization +This option isn't valid for the following index-based string operations: +IndexOf, LastIndexOf, StartsWith, EndsWith, IsPrefix, and IsSuffix. -Bir kaç işimize yarayabilecek serileştirme güncellemesi var ama biz Newtonsoft -kullanıyoruz. +## SDK -https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/libraries#serialization +### SLNX file format -## SDK +sln dosyaları slnx olacak ### Support for Microsoft Testing Platform in dotnet test @@ -79,7 +76,7 @@ public record Product( ``` ### `IProblemDetailsService` - +bir örnek yap Defines a type that provide functionality to create a ProblemDetails response. Bu 7'den sonra da varmış. Kullanmamışız. Ben yinede ekliyim belki şimdi bazı şeyleri kolaylayabilir. @@ -129,7 +126,7 @@ OpenApiOperation operation = new OpenApiOperation [daha fazla 2.0 değişikliği için](https://github.com/microsoft/OpenAPI.NET/blob/main/docs/upgrade-guide-2.md) -### Authenticatio and authorization +### Authentication and authorization #### Avoid cookie login redirects for known API endpoints @@ -168,7 +165,7 @@ redirecturl locale e mi gidecek diye bakıyor. locale se true dönüyor. ### Extension members yeni extension yazma yöntemleri geldi - +bu syntax a geçilecek ```csharp public static class Enumerable { @@ -250,6 +247,7 @@ sanırım eskiden +=, -=, *= gibi operatorleri kendin yazamıyordun. artık yazılabiliyor gibi tam olarak hangilerine izin var tam anlamadım https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-14.0/user-defined-compound-assignment + ### Null-Conditional Assignment atamalarda if ile not null kontrolüne gerek kalmamış From 79d0b008c3cf01c860fd1fbb86fec793fb118abe Mon Sep 17 00:00:00 2001 From: Sefer Mirza Date: Wed, 4 Mar 2026 15:49:29 +0300 Subject: [PATCH 06/29] add migration notes --- dotnet-10-research-notes.md | 59 +++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md index fa5b60a..0966d7b 100644 --- a/dotnet-10-research-notes.md +++ b/dotnet-10-research-notes.md @@ -23,6 +23,21 @@ foreach (string os in new[] { "Windows 11", "Windows 10", "Windows 8" }.Order(nu This option isn't valid for the following index-based string operations: IndexOf, LastIndexOf, StartsWith, EndsWith, IsPrefix, and IsSuffix. +#### AsyncEnumerable + +The [AsyncEnumerable](https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable) class in .NET 10, and in the [`System.Linq.AsyncEnumerable` NuGet package](https://www.nuget.org/packages/System.Linq.AsyncEnumerable/), provides LINQ support for [IAsyncEnumerable<T>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1). + +## Networking + +### Streaming HTTP responses enabled by default in browser HTTP clients + +The [HttpContent](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent) no longer contains a [MemoryStream](https://learn.microsoft.com/en-us/dotnet/api/system.io.memorystream). Instead, [HttpContent.ReadAsStreamAsync](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync) returns a `BrowserHttpReadStream`, which does not support synchronous operations. + +```csharp +var response = await httpClient.GetAsync("https://example.com"); +var contentStream = await response.Content.ReadAsStreamAsync(); // Returns BrowserHttpReadStream instead of MemoryStream +``` + ## SDK ### SLNX file format @@ -44,11 +59,44 @@ feature, add the following configuration to your global.json file: [MTP](https://learn.microsoft.com/en-us/dotnet/core/testing/microsoft-testing-platform-intro) +### .NET CLI `--interactive` defaults to `true` in user scenarios + +bu interactive default olarak true yapılmış. `dotnet restore` tarafında bir sorun çıkarsa +bundan kaynaklı olabilir. `--interactive false` şeklinde verilerek tekrar kapatılabilir + +### Code coverage EnableDynamicNativeInstrumentation defaults to false + +büyük ihtimalle bizi etkilemeyecek ama depend edilen kütüphanelerle ilgili problem olursa diye +not olarak ekliyorum. + +coverage collect te EnableDynamicNativeInstrumentation false yapılmış. native araçlardan +coverage almada sorun çıkarıyor bu flag + +### dotnet restore audits transitive packages + +audit warningleri default olarak seviye atlatılmış. bizde warningler error olarak gösterildiğinden +restorelarda sorun yaratabilir. + +```xml + + + + +yada + + + NU1901;NU1902;NU1903;NU1904;$(WarningsNotAsErrors) + +``` + + + ## ASP.NET ### Treating empty string in form post as null for nullable value types When using the [FromForm] attribute + ```csharp app.MapPost("/todo", ([FromForm] Todo todo) => TypedResults.Ok(todo)); @@ -76,6 +124,7 @@ public record Product( ``` ### `IProblemDetailsService` + bir örnek yap Defines a type that provide functionality to create a ProblemDetails response. @@ -160,12 +209,18 @@ yönlendirme yerine doğrudan 401 ve 403 döndürüyor. `RedirectHttpResult.IsLocalUrl` diye bir helper gelmiş. url veriyorsun oradaki redirecturl locale e mi gidecek diye bakıyor. locale se true dönüyor. +#### Exception diagnostics are suppressed when IExceptionHandler.TryHandleAsync returns true + +`IExceptionHandler` ile exception'ları handle ettiğinde(true döndüğünde) artık o exception +için otomatik olarak log ve telemetry yazılmıyor + ## C# 14 ### Extension members yeni extension yazma yöntemleri geldi bu syntax a geçilecek + ```csharp public static class Enumerable { @@ -208,7 +263,7 @@ public string Name ### Implicit Span Conversions -Span ve ReadOnlySpan için, ReadOnlySpan, Span ve T[] türlerine +Span `` ve ReadOnlySpan `` için, ReadOnlySpan ``, Span `` ve T[] türlerine implicit cast gelmiş ```csharp @@ -256,4 +311,4 @@ atamalarda if ile not null kontrolüne gerek kalmamış customer?.Order = GetCurrentOrder(); ``` -ama +=, -= falan desteklemiyor \ No newline at end of file +ama +=, -= falan desteklemiyor From 2c1c1cff5fc77995689623f6033cabd5e79602af Mon Sep 17 00:00:00 2001 From: Sefer Mirza Date: Wed, 4 Mar 2026 18:31:18 +0300 Subject: [PATCH 07/29] add migration tasks --- dotnet-10-research-notes.md | 65 +++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md index 0966d7b..1ad5782 100644 --- a/dotnet-10-research-notes.md +++ b/dotnet-10-research-notes.md @@ -1,5 +1,64 @@ # .NET 10 Research Notes +## Learn Tasks + +- [ ] install dotnet 10 +- [ ] upgrade dotnet version to `10` +- [ ] upgrade c# version to `14` +- [ ] make sure packages fine with dotnet 10 +- [ ] + +## Migration Tasks + +> [!INFO] This task are temp + +- [ ] install dotnet 10 +- [ ] upgrade dotnet version to `10` +- [ ] upgrade c# version to `14` +- [ ] make sure packages fine with dotnet 10 +- Opportunistic Improvements + - [ ] Use `CompareOptions.NumericOrdering` property of the `StringComparer` + object if it will make things easier + - [ ] At first glance, it didn't seem necessary, but if needed, it looks like + description support has been added to `ProducesAttribute`, + `ProducesResponseTypeAttribute`, and `ProducesDefaultResponseTypeAttribute` + - [ ] Use `RedirectHttpResult.IsLocalUrl` in places that check whether the URL + redirects to the locale or externally + - [ ] Use if necessary, the `field` keyword in properties + - [ ] Now allows `nameof` for unbound generics. If there were different + approaches previously because it wasn't allowed, these can be simplified + - [ ] The partial constructor feature now supported. Use it if we need to + - probably, the analyzer will already warn you, but just in case; + - [ ] use implicit `Span` conversions to array + - [ ] use simple lambda parameters with modifiers + - [ ] use Null-Conditional assignment + - do if okay after learn + - [ ] if it is really necessary, use the validation attributes in response + records + - [ ] if necessary, edit the response of unhandled errors with + `IProblemDetailsService` +- Required Migrations + - [ ] use `.slnx` instead of `.sln` + - [ ] use extension members + - Property extensions will be used for those that do not take parameters and + for specifying layer builders. exp: `configure.Ui.ComponentPresets(...)` + - if okay after learn + - [ ] use `Microsoft Testing Platform` for testing +- Troubleshooting & Pitfalls(You should also test the tasks that can be checked + to be sure) + - `HttpContent` now returns `BrowserHttpReadStream` instead of `MemoryStream` + - The warning level for audits has been raised in `dotnet restore`. If the + error encountered cannot be resolved, the warning level can be lowered in + `Directory.Build.props` or the relevant warning can be ignored + - Validation APIs moved to `Microsoft.Extensions.Validation` + - If you encounter any issues with OpenAPI, check [here](https://github.com/microsoft/OpenAPI.NET/blob/main/docs/upgrade-guide-2.md) + - [ ] If `dotnet restore` is waiting for user input, it should be set to + `--interactive false` + - [ ] If you encounter an error or receive incorrect results when obtaining + coverage, you may need to set `EnableDynamicNativeInstrumentation` to `true` + - [ ] Now, in form post actions, `nullable` fields are automatically set to + null when they receive an empty string + ## Libraries ### Numeric ordering for string comparison @@ -23,10 +82,6 @@ foreach (string os in new[] { "Windows 11", "Windows 10", "Windows 8" }.Order(nu This option isn't valid for the following index-based string operations: IndexOf, LastIndexOf, StartsWith, EndsWith, IsPrefix, and IsSuffix. -#### AsyncEnumerable - -The [AsyncEnumerable](https://learn.microsoft.com/en-us/dotnet/api/system.linq.asyncenumerable) class in .NET 10, and in the [`System.Linq.AsyncEnumerable` NuGet package](https://www.nuget.org/packages/System.Linq.AsyncEnumerable/), provides LINQ support for [IAsyncEnumerable<T>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1). - ## Networking ### Streaming HTTP responses enabled by default in browser HTTP clients @@ -89,8 +144,6 @@ yada ``` - - ## ASP.NET ### Treating empty string in form post as null for nullable value types From 041c27f010d4237449829d77fc45bccca735a161 Mon Sep 17 00:00:00 2001 From: Sefer Mirza Date: Wed, 4 Mar 2026 18:58:01 +0300 Subject: [PATCH 08/29] edit document --- dotnet-10-research-notes.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md index 1ad5782..d47bad3 100644 --- a/dotnet-10-research-notes.md +++ b/dotnet-10-research-notes.md @@ -1,13 +1,5 @@ # .NET 10 Research Notes -## Learn Tasks - -- [ ] install dotnet 10 -- [ ] upgrade dotnet version to `10` -- [ ] upgrade c# version to `14` -- [ ] make sure packages fine with dotnet 10 -- [ ] - ## Migration Tasks > [!INFO] This task are temp From be891f31854849baa20680041ab2f82c1d94213b Mon Sep 17 00:00:00 2001 From: Sefer Mirza Date: Wed, 4 Mar 2026 19:03:22 +0300 Subject: [PATCH 09/29] add note --- dotnet-10-research-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md index d47bad3..afd3a3e 100644 --- a/dotnet-10-research-notes.md +++ b/dotnet-10-research-notes.md @@ -1,3 +1,4 @@ + # .NET 10 Research Notes ## Migration Tasks From d91b28f2a7d34d1912190cd63ac34f1bffcfd64a Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Thu, 5 Mar 2026 14:53:42 +0300 Subject: [PATCH 10/29] init 'issue/dotnet-10/extension-members' --- Directory.Build.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index bf92fb2..5f334af 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,8 +1,8 @@ - net9.0 - 13.0 + net10.0 + 14.0 true enable enable From 063ae1b0d05bded507859b004562e39546445919 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Thu, 5 Mar 2026 16:08:03 +0300 Subject: [PATCH 11/29] fix build --- Directory.Packages.props | 52 +++++++++---------- aspire/Aspire.ServiceDefaults/Extensions.cs | 6 +-- localization/Localization/Localization.csproj | 1 - .../AddParameterToPostOperations.cs | 5 +- .../DocumentBasedSecurityDefinition.cs | 5 +- .../DocumentBasedSecurityRequirement.cs | 15 +++--- swashbuckle/Swashbuckle/Program.cs | 9 ++-- swashbuckle/Swashbuckle/Swashbuckle.csproj | 1 + 8 files changed, 48 insertions(+), 46 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 52ff8b5..a36a391 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,36 +5,36 @@ - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + - - - - + + + + - + \ No newline at end of file diff --git a/aspire/Aspire.ServiceDefaults/Extensions.cs b/aspire/Aspire.ServiceDefaults/Extensions.cs index 0a2ee48..761d34f 100644 --- a/aspire/Aspire.ServiceDefaults/Extensions.cs +++ b/aspire/Aspire.ServiceDefaults/Extensions.cs @@ -51,9 +51,9 @@ public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicati }) .WithTracing(tracing => { + // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) + //.AddGrpcClientInstrumentation() tracing.AddAspNetCoreInstrumentation() - // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) - //.AddGrpcClientInstrumentation() .AddHttpClientInstrumentation(); }); @@ -83,8 +83,8 @@ private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostAppli public static IHostApplicationBuilder AddDefaultHealthChecks(this IHostApplicationBuilder builder) { + // Add a default liveness check to ensure app is responsive builder.Services.AddHealthChecks() - // Add a default liveness check to ensure app is responsive .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]); return builder; diff --git a/localization/Localization/Localization.csproj b/localization/Localization/Localization.csproj index 34a4e91..57b18e6 100644 --- a/localization/Localization/Localization.csproj +++ b/localization/Localization/Localization.csproj @@ -5,7 +5,6 @@ - diff --git a/swashbuckle/Swashbuckle/AddParameterToPostOperations.cs b/swashbuckle/Swashbuckle/AddParameterToPostOperations.cs index a54a3c9..a1f7777 100644 --- a/swashbuckle/Swashbuckle/AddParameterToPostOperations.cs +++ b/swashbuckle/Swashbuckle/AddParameterToPostOperations.cs @@ -1,4 +1,4 @@ -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; using Swashbuckle.AspNetCore.SwaggerGen; namespace Swashbuckle; @@ -10,7 +10,8 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) { if (context.ApiDescription.HttpMethod != "POST") { return; } - operation.Parameters.Insert(0, new() + operation.Parameters ??= []; + operation.Parameters.Insert(0, new OpenApiParameter { In = _in, Name = _name, diff --git a/swashbuckle/Swashbuckle/DocumentBasedSecurityDefinition.cs b/swashbuckle/Swashbuckle/DocumentBasedSecurityDefinition.cs index afe4910..c210166 100644 --- a/swashbuckle/Swashbuckle/DocumentBasedSecurityDefinition.cs +++ b/swashbuckle/Swashbuckle/DocumentBasedSecurityDefinition.cs @@ -1,4 +1,4 @@ -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; using Swashbuckle.AspNetCore.SwaggerGen; namespace Swashbuckle; @@ -10,6 +10,9 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { if (context.DocumentName != document) { return; } + swaggerDoc.Components ??= new OpenApiComponents(); + swaggerDoc.Components.SecuritySchemes ??= new Dictionary(); + swaggerDoc.Components.SecuritySchemes[_schemeId] = _scheme; } } \ No newline at end of file diff --git a/swashbuckle/Swashbuckle/DocumentBasedSecurityRequirement.cs b/swashbuckle/Swashbuckle/DocumentBasedSecurityRequirement.cs index 18e6d00..8b791f7 100644 --- a/swashbuckle/Swashbuckle/DocumentBasedSecurityRequirement.cs +++ b/swashbuckle/Swashbuckle/DocumentBasedSecurityRequirement.cs @@ -1,4 +1,4 @@ -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; using Swashbuckle.AspNetCore.SwaggerGen; namespace Swashbuckle; @@ -10,12 +10,13 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) { if (context.DocumentName != _document) { return; } - operation.Security.Add(new() + operation.Security ??= []; + + var requirement = new OpenApiSecurityRequirement { - { - new() { Reference = new() { Type = ReferenceType.SecurityScheme, Id = _schemeId } }, - Array.Empty() - } - }); + { new OpenApiSecuritySchemeReference(_schemeId), [] }, + }; + + operation.Security.Add(requirement); } } \ No newline at end of file diff --git a/swashbuckle/Swashbuckle/Program.cs b/swashbuckle/Swashbuckle/Program.cs index 15e64df..73b2b65 100644 --- a/swashbuckle/Swashbuckle/Program.cs +++ b/swashbuckle/Swashbuckle/Program.cs @@ -1,4 +1,4 @@ -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; using Swashbuckle; using Swashbuckle.AspNetCore.SwaggerGen; @@ -22,11 +22,8 @@ // custom metadata swaggerGenOptions.DocInclusionPredicate((document, api) => - // doc exclusion - !api.CustomAttributes().OfType().Any() && - - // multi doc - api.CustomAttributes().OfType().SingleOrDefault()?.Name == document + !api.CustomAttributes().OfType().Any() && // doc exclusion + api.CustomAttributes().OfType().SingleOrDefault()?.Name == document // multi doc ); // security config diff --git a/swashbuckle/Swashbuckle/Swashbuckle.csproj b/swashbuckle/Swashbuckle/Swashbuckle.csproj index 2d70ad3..a3b6c2d 100644 --- a/swashbuckle/Swashbuckle/Swashbuckle.csproj +++ b/swashbuckle/Swashbuckle/Swashbuckle.csproj @@ -1,6 +1,7 @@ + From 4d7baedf22e358857296480a6cbe7eb35a1ba708 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Thu, 5 Mar 2026 17:17:32 +0300 Subject: [PATCH 12/29] make inline security adding --- .../Swashbuckle/DocumentBasedSecurityRequirement.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/swashbuckle/Swashbuckle/DocumentBasedSecurityRequirement.cs b/swashbuckle/Swashbuckle/DocumentBasedSecurityRequirement.cs index 8b791f7..ec4b961 100644 --- a/swashbuckle/Swashbuckle/DocumentBasedSecurityRequirement.cs +++ b/swashbuckle/Swashbuckle/DocumentBasedSecurityRequirement.cs @@ -11,12 +11,10 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) if (context.DocumentName != _document) { return; } operation.Security ??= []; - - var requirement = new OpenApiSecurityRequirement - { - { new OpenApiSecuritySchemeReference(_schemeId), [] }, - }; - - operation.Security.Add(requirement); + operation.Security.Add(new() + { + { new OpenApiSecuritySchemeReference(_schemeId), [] }, + } + ); } } \ No newline at end of file From c7008226d40c4cf17ad0e147fe5eb2a652854e39 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Thu, 5 Mar 2026 17:35:02 +0300 Subject: [PATCH 13/29] sln migrate --- learn-dotnet.sln | 335 ---------------------------------------------- learn-dotnet.slnx | 97 ++++++++++++++ 2 files changed, 97 insertions(+), 335 deletions(-) delete mode 100644 learn-dotnet.sln create mode 100644 learn-dotnet.slnx diff --git a/learn-dotnet.sln b/learn-dotnet.sln deleted file mode 100644 index 63677e7..0000000 --- a/learn-dotnet.sln +++ /dev/null @@ -1,335 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "analyzers", "analyzers", "{AF835CF7-F63E-4667-A84D-298D4FF2E095}" - ProjectSection(SolutionItems) = preProject - analyzers\README.md = analyzers\README.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "central-package-management", "central-package-management", "{1388F723-B25D-4020-8F5B-B7A4B2BD067F}" - ProjectSection(SolutionItems) = preProject - central-package-management\README.md = central-package-management\README.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectA", "central-package-management\ProjectA\ProjectA.csproj", "{C5868FAC-1628-4400-8018-7DD14E4A6119}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectB", "central-package-management\ProjectB\ProjectB.csproj", "{6AB76071-4AF2-49EF-ACDC-3F5EEBC73958}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependency-injection", "dependency-injection", "{EA678579-BA95-403B-A700-5878CD3A13DD}" - ProjectSection(SolutionItems) = preProject - dependency-injection\README.md = dependency-injection\README.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nullable-usage", "nullable-usage", "{1194D255-B8CE-4268-B5EA-8EB36A3A758F}" - ProjectSection(SolutionItems) = preProject - nullable-usage\README.md = nullable-usage\README.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NullableUsage", "nullable-usage\NullableUsage\NullableUsage.csproj", "{0480A21D-4A63-4372-9AE1-77D60B56FB46}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "source-generator", "source-generator", "{64526710-CEFE-40C7-AA39-B2A1A87FF203}" - ProjectSection(SolutionItems) = preProject - source-generator\README.md = source-generator\README.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cli", "Cli", "{AA74E944-135B-4227-9C3C-ECD46406B1A4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cli", "source-generator\Cli\Cli.csproj", "{1B87270E-1B6A-4E05-B6F4-5FA2435738BE}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CodeGen", "CodeGen", "{163CC013-E841-49A8-8A62-68B467683CE6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CodeGen", "source-generator\CodeGen\CodeGen.csproj", "{0A91A2DA-6490-4EE5-AA0F-1B055966830C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Domain", "Domain", "{FAA54A28-B96D-494F-87CB-E823160D262D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Domain", "source-generator\Domain\Domain.csproj", "{FA89943C-FD8E-42C5-A2F9-23C58952C0D9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebApp", "WebApp", "{5F662200-07DC-4221-843C-AEAE137E4B96}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApp", "source-generator\WebApp\WebApp.csproj", "{5E26550D-8556-425E-99B9-9E932B931E2C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unit-testing", "unit-testing", "{A3F73601-24CF-4396-B688-EA53EF91A4D4}" - ProjectSection(SolutionItems) = preProject - unit-testing\README.md = unit-testing\README.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B9D12006-ABDC-42F2-8519-6C75A6A2554D}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - README.md = README.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{E148C898-1BFD-4F28-8940-583CC50F90DB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTesting", "unit-testing\UnitTesting\UnitTesting.csproj", "{50715692-EE4A-4DE9-BA64-3226C20E7EFD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DependencyInjection", "dependency-injection\DependencyInjection\DependencyInjection.csproj", "{50657568-23CD-4307-AB2E-86A3B03ECB01}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "publish-over-dockerfile", "publish-over-dockerfile", "{1B4C5600-1E5A-4797-B675-C459C7FB5454}" - ProjectSection(SolutionItems) = preProject - publish-over-dockerfile\README.md = publish-over-dockerfile\README.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "regex-source-generators", "regex-source-generators", "{F93CB7AF-CA43-4D1E-883F-EEB4930FC679}" - ProjectSection(SolutionItems) = preProject - regex-source-generators\README.md = regex-source-generators\README.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RegexSourceGenerators", "regex-source-generators\RegexSourceGenerators\RegexSourceGenerators.csproj", "{E9414ABB-3845-47C8-96AA-BAA4FEC51B7E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PublishOverDockerfile", "publish-over-dockerfile\PublishOverDockerfile\PublishOverDockerfile.csproj", "{51E8C5A1-9789-4619-8ACE-D25DB5460413}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "primary-constructor", "primary-constructor", "{3892B517-E16C-4BDB-8EE0-CB80F66C3B19}" - ProjectSection(SolutionItems) = preProject - primary-constructor\README.md = primary-constructor\README.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PrimaryConstructor", "primary-constructor\PrimaryConstructor\PrimaryConstructor.csproj", "{88921AF0-2327-4E02-A9FE-201C37670C01}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "exception-handling", "exception-handling", "{1D0A109B-6458-4C04-B400-F9484310595C}" - ProjectSection(SolutionItems) = preProject - exception-handling\README.md = exception-handling\README.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExceptionHandling", "exception-handling\ExceptionHandling\ExceptionHandling.csproj", "{658DFE92-7D9E-4DD6-979C-57460629A5E2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp", "csharp", "{8D3DAA2C-A035-47DC-92DE-A0DA501B32BF}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "native-aot", "native-aot", "{A6FDF528-DB3B-4838-8D9D-F3E0F08DF97A}" - ProjectSection(SolutionItems) = preProject - native-aot\README.md = native-aot\README.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeAOT", "native-aot\NativeAOT\NativeAOT.csproj", "{AD006E83-4501-47B5-BEEA-BA9326A3D630}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharp", "csharp\CSharp\CSharp.csproj", "{7299B336-9340-4E15-B0EE-B59C2770D7EE}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarking-in-dotnet", "benchmarking-in-dotnet", "{32202E5E-02C2-48CA-9D8D-687146EB0232}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarkingInDotNet", "benchmarking-in-dotnet\BenchmarkingInDotNet\BenchmarkingInDotNet.csproj", "{6E92E509-834F-403C-A0B0-3B691F3C816D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "model-binders", "model-binders", "{1828D64E-F976-4B87-B37C-BD9E694E9482}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModelBinders", "model-binders\ModelBinders\ModelBinders.csproj", "{382B91E4-9043-4261-BBE7-BEA9C0137C07}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AnalyzersSample", "analyzers\AnalyzersSample\AnalyzersSample.csproj", "{F7185339-B401-483F-8FB5-FBC9A1D4DBFC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "authentication", "authentication", "{8E574EE1-3694-4905-B0FA-BEE599B5C0F9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultiAuthentication", "authentication\MultiAuthentication\MultiAuthentication.csproj", "{4719C295-752C-4464-8A7D-151A1B8A37DD}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "swashbuckle", "swashbuckle", "{CC39E923-166C-43EB-BD80-6B89122CF7A5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Swashbuckle", "swashbuckle\Swashbuckle\Swashbuckle.csproj", "{C4535DDC-D848-4238-B99D-ED0C9767D64C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "openapi", "openapi", "{5EFD2336-9236-4C29-9CFD-077E702D6ACD}" - ProjectSection(SolutionItems) = preProject - openapi\README.md = openapi\README.md - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenAPI", "openapi\OpenAPI\OpenAPI.csproj", "{AD45E9C7-D739-4513-8F01-3A6826E0F4FA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "reflection", "reflection", "{5771998F-DD44-4CEA-8B37-C2E90E5014AC}" - ProjectSection(SolutionItems) = preProject - reflection\README.md = reflection\README.md - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reflection", "reflection\Reflection\Reflection.csproj", "{E0B6EFF9-41D8-4EDF-8303-5977D6637FF6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "aspire", "aspire", "{6EAC4719-E994-426D-87BD-6BB12FF17232}" - ProjectSection(SolutionItems) = preProject - aspire\README.md = aspire\README.md - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aspire.AppHost", "aspire\Aspire.AppHost\Aspire.AppHost.csproj", "{FF280BA1-B772-48AC-8110-065520F3B852}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aspire.ServiceDefaults", "aspire\Aspire.ServiceDefaults\Aspire.ServiceDefaults.csproj", "{EA1FCF65-B230-4932-9164-85C2E39449BC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectA", "aspire\ProjectA\ProjectA.csproj", "{1F34FA6D-124F-42AD-BE5F-F31FF07B9E28}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectB", "aspire\ProjectB\ProjectB.csproj", "{0DCC0BF3-FDFF-4AF7-A080-6A5D9213386F}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "localization", "localization", "{9F730981-E25D-4857-B870-B98B0398688B}" - ProjectSection(SolutionItems) = preProject - localization\README.md = localization\README.md - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Localization", "localization\Localization\Localization.csproj", "{614740C2-6A5E-4F93-BD55-C3DF9B7EF33F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C5868FAC-1628-4400-8018-7DD14E4A6119}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C5868FAC-1628-4400-8018-7DD14E4A6119}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C5868FAC-1628-4400-8018-7DD14E4A6119}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C5868FAC-1628-4400-8018-7DD14E4A6119}.Release|Any CPU.Build.0 = Release|Any CPU - {6AB76071-4AF2-49EF-ACDC-3F5EEBC73958}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6AB76071-4AF2-49EF-ACDC-3F5EEBC73958}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6AB76071-4AF2-49EF-ACDC-3F5EEBC73958}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6AB76071-4AF2-49EF-ACDC-3F5EEBC73958}.Release|Any CPU.Build.0 = Release|Any CPU - {0480A21D-4A63-4372-9AE1-77D60B56FB46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0480A21D-4A63-4372-9AE1-77D60B56FB46}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0480A21D-4A63-4372-9AE1-77D60B56FB46}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0480A21D-4A63-4372-9AE1-77D60B56FB46}.Release|Any CPU.Build.0 = Release|Any CPU - {1B87270E-1B6A-4E05-B6F4-5FA2435738BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1B87270E-1B6A-4E05-B6F4-5FA2435738BE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1B87270E-1B6A-4E05-B6F4-5FA2435738BE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1B87270E-1B6A-4E05-B6F4-5FA2435738BE}.Release|Any CPU.Build.0 = Release|Any CPU - {0A91A2DA-6490-4EE5-AA0F-1B055966830C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0A91A2DA-6490-4EE5-AA0F-1B055966830C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0A91A2DA-6490-4EE5-AA0F-1B055966830C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0A91A2DA-6490-4EE5-AA0F-1B055966830C}.Release|Any CPU.Build.0 = Release|Any CPU - {FA89943C-FD8E-42C5-A2F9-23C58952C0D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FA89943C-FD8E-42C5-A2F9-23C58952C0D9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FA89943C-FD8E-42C5-A2F9-23C58952C0D9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FA89943C-FD8E-42C5-A2F9-23C58952C0D9}.Release|Any CPU.Build.0 = Release|Any CPU - {5E26550D-8556-425E-99B9-9E932B931E2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5E26550D-8556-425E-99B9-9E932B931E2C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5E26550D-8556-425E-99B9-9E932B931E2C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5E26550D-8556-425E-99B9-9E932B931E2C}.Release|Any CPU.Build.0 = Release|Any CPU - {50715692-EE4A-4DE9-BA64-3226C20E7EFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {50715692-EE4A-4DE9-BA64-3226C20E7EFD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {50715692-EE4A-4DE9-BA64-3226C20E7EFD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {50715692-EE4A-4DE9-BA64-3226C20E7EFD}.Release|Any CPU.Build.0 = Release|Any CPU - {50657568-23CD-4307-AB2E-86A3B03ECB01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {50657568-23CD-4307-AB2E-86A3B03ECB01}.Debug|Any CPU.Build.0 = Debug|Any CPU - {50657568-23CD-4307-AB2E-86A3B03ECB01}.Release|Any CPU.ActiveCfg = Release|Any CPU - {50657568-23CD-4307-AB2E-86A3B03ECB01}.Release|Any CPU.Build.0 = Release|Any CPU - {E9414ABB-3845-47C8-96AA-BAA4FEC51B7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E9414ABB-3845-47C8-96AA-BAA4FEC51B7E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E9414ABB-3845-47C8-96AA-BAA4FEC51B7E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E9414ABB-3845-47C8-96AA-BAA4FEC51B7E}.Release|Any CPU.Build.0 = Release|Any CPU - {51E8C5A1-9789-4619-8ACE-D25DB5460413}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {51E8C5A1-9789-4619-8ACE-D25DB5460413}.Debug|Any CPU.Build.0 = Debug|Any CPU - {51E8C5A1-9789-4619-8ACE-D25DB5460413}.Release|Any CPU.ActiveCfg = Release|Any CPU - {51E8C5A1-9789-4619-8ACE-D25DB5460413}.Release|Any CPU.Build.0 = Release|Any CPU - {88921AF0-2327-4E02-A9FE-201C37670C01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {88921AF0-2327-4E02-A9FE-201C37670C01}.Debug|Any CPU.Build.0 = Debug|Any CPU - {88921AF0-2327-4E02-A9FE-201C37670C01}.Release|Any CPU.ActiveCfg = Release|Any CPU - {88921AF0-2327-4E02-A9FE-201C37670C01}.Release|Any CPU.Build.0 = Release|Any CPU - {658DFE92-7D9E-4DD6-979C-57460629A5E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {658DFE92-7D9E-4DD6-979C-57460629A5E2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {658DFE92-7D9E-4DD6-979C-57460629A5E2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {658DFE92-7D9E-4DD6-979C-57460629A5E2}.Release|Any CPU.Build.0 = Release|Any CPU - {AD006E83-4501-47B5-BEEA-BA9326A3D630}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AD006E83-4501-47B5-BEEA-BA9326A3D630}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AD006E83-4501-47B5-BEEA-BA9326A3D630}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AD006E83-4501-47B5-BEEA-BA9326A3D630}.Release|Any CPU.Build.0 = Release|Any CPU - {7299B336-9340-4E15-B0EE-B59C2770D7EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7299B336-9340-4E15-B0EE-B59C2770D7EE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7299B336-9340-4E15-B0EE-B59C2770D7EE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7299B336-9340-4E15-B0EE-B59C2770D7EE}.Release|Any CPU.Build.0 = Release|Any CPU - {6E92E509-834F-403C-A0B0-3B691F3C816D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6E92E509-834F-403C-A0B0-3B691F3C816D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6E92E509-834F-403C-A0B0-3B691F3C816D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6E92E509-834F-403C-A0B0-3B691F3C816D}.Release|Any CPU.Build.0 = Release|Any CPU - {382B91E4-9043-4261-BBE7-BEA9C0137C07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {382B91E4-9043-4261-BBE7-BEA9C0137C07}.Debug|Any CPU.Build.0 = Debug|Any CPU - {382B91E4-9043-4261-BBE7-BEA9C0137C07}.Release|Any CPU.ActiveCfg = Release|Any CPU - {382B91E4-9043-4261-BBE7-BEA9C0137C07}.Release|Any CPU.Build.0 = Release|Any CPU - {F7185339-B401-483F-8FB5-FBC9A1D4DBFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7185339-B401-483F-8FB5-FBC9A1D4DBFC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7185339-B401-483F-8FB5-FBC9A1D4DBFC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7185339-B401-483F-8FB5-FBC9A1D4DBFC}.Release|Any CPU.Build.0 = Release|Any CPU - {4719C295-752C-4464-8A7D-151A1B8A37DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4719C295-752C-4464-8A7D-151A1B8A37DD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4719C295-752C-4464-8A7D-151A1B8A37DD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4719C295-752C-4464-8A7D-151A1B8A37DD}.Release|Any CPU.Build.0 = Release|Any CPU - {C4535DDC-D848-4238-B99D-ED0C9767D64C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C4535DDC-D848-4238-B99D-ED0C9767D64C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C4535DDC-D848-4238-B99D-ED0C9767D64C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C4535DDC-D848-4238-B99D-ED0C9767D64C}.Release|Any CPU.Build.0 = Release|Any CPU - {AD45E9C7-D739-4513-8F01-3A6826E0F4FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AD45E9C7-D739-4513-8F01-3A6826E0F4FA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AD45E9C7-D739-4513-8F01-3A6826E0F4FA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AD45E9C7-D739-4513-8F01-3A6826E0F4FA}.Release|Any CPU.Build.0 = Release|Any CPU - {E0B6EFF9-41D8-4EDF-8303-5977D6637FF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E0B6EFF9-41D8-4EDF-8303-5977D6637FF6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E0B6EFF9-41D8-4EDF-8303-5977D6637FF6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E0B6EFF9-41D8-4EDF-8303-5977D6637FF6}.Release|Any CPU.Build.0 = Release|Any CPU - {FF280BA1-B772-48AC-8110-065520F3B852}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FF280BA1-B772-48AC-8110-065520F3B852}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FF280BA1-B772-48AC-8110-065520F3B852}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FF280BA1-B772-48AC-8110-065520F3B852}.Release|Any CPU.Build.0 = Release|Any CPU - {EA1FCF65-B230-4932-9164-85C2E39449BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EA1FCF65-B230-4932-9164-85C2E39449BC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EA1FCF65-B230-4932-9164-85C2E39449BC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EA1FCF65-B230-4932-9164-85C2E39449BC}.Release|Any CPU.Build.0 = Release|Any CPU - {1F34FA6D-124F-42AD-BE5F-F31FF07B9E28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1F34FA6D-124F-42AD-BE5F-F31FF07B9E28}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1F34FA6D-124F-42AD-BE5F-F31FF07B9E28}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1F34FA6D-124F-42AD-BE5F-F31FF07B9E28}.Release|Any CPU.Build.0 = Release|Any CPU - {0DCC0BF3-FDFF-4AF7-A080-6A5D9213386F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0DCC0BF3-FDFF-4AF7-A080-6A5D9213386F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0DCC0BF3-FDFF-4AF7-A080-6A5D9213386F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0DCC0BF3-FDFF-4AF7-A080-6A5D9213386F}.Release|Any CPU.Build.0 = Release|Any CPU - {614740C2-6A5E-4F93-BD55-C3DF9B7EF33F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {614740C2-6A5E-4F93-BD55-C3DF9B7EF33F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {614740C2-6A5E-4F93-BD55-C3DF9B7EF33F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {614740C2-6A5E-4F93-BD55-C3DF9B7EF33F}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {AF835CF7-F63E-4667-A84D-298D4FF2E095} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {1388F723-B25D-4020-8F5B-B7A4B2BD067F} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {C5868FAC-1628-4400-8018-7DD14E4A6119} = {1388F723-B25D-4020-8F5B-B7A4B2BD067F} - {6AB76071-4AF2-49EF-ACDC-3F5EEBC73958} = {1388F723-B25D-4020-8F5B-B7A4B2BD067F} - {EA678579-BA95-403B-A700-5878CD3A13DD} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {1194D255-B8CE-4268-B5EA-8EB36A3A758F} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {0480A21D-4A63-4372-9AE1-77D60B56FB46} = {1194D255-B8CE-4268-B5EA-8EB36A3A758F} - {64526710-CEFE-40C7-AA39-B2A1A87FF203} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {AA74E944-135B-4227-9C3C-ECD46406B1A4} = {64526710-CEFE-40C7-AA39-B2A1A87FF203} - {1B87270E-1B6A-4E05-B6F4-5FA2435738BE} = {AA74E944-135B-4227-9C3C-ECD46406B1A4} - {163CC013-E841-49A8-8A62-68B467683CE6} = {64526710-CEFE-40C7-AA39-B2A1A87FF203} - {0A91A2DA-6490-4EE5-AA0F-1B055966830C} = {163CC013-E841-49A8-8A62-68B467683CE6} - {FAA54A28-B96D-494F-87CB-E823160D262D} = {64526710-CEFE-40C7-AA39-B2A1A87FF203} - {FA89943C-FD8E-42C5-A2F9-23C58952C0D9} = {FAA54A28-B96D-494F-87CB-E823160D262D} - {5F662200-07DC-4221-843C-AEAE137E4B96} = {64526710-CEFE-40C7-AA39-B2A1A87FF203} - {5E26550D-8556-425E-99B9-9E932B931E2C} = {5F662200-07DC-4221-843C-AEAE137E4B96} - {A3F73601-24CF-4396-B688-EA53EF91A4D4} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {50715692-EE4A-4DE9-BA64-3226C20E7EFD} = {A3F73601-24CF-4396-B688-EA53EF91A4D4} - {50657568-23CD-4307-AB2E-86A3B03ECB01} = {EA678579-BA95-403B-A700-5878CD3A13DD} - {1B4C5600-1E5A-4797-B675-C459C7FB5454} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {F93CB7AF-CA43-4D1E-883F-EEB4930FC679} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {E9414ABB-3845-47C8-96AA-BAA4FEC51B7E} = {F93CB7AF-CA43-4D1E-883F-EEB4930FC679} - {51E8C5A1-9789-4619-8ACE-D25DB5460413} = {1B4C5600-1E5A-4797-B675-C459C7FB5454} - {3892B517-E16C-4BDB-8EE0-CB80F66C3B19} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {88921AF0-2327-4E02-A9FE-201C37670C01} = {3892B517-E16C-4BDB-8EE0-CB80F66C3B19} - {1D0A109B-6458-4C04-B400-F9484310595C} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {658DFE92-7D9E-4DD6-979C-57460629A5E2} = {1D0A109B-6458-4C04-B400-F9484310595C} - {8D3DAA2C-A035-47DC-92DE-A0DA501B32BF} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {A6FDF528-DB3B-4838-8D9D-F3E0F08DF97A} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {AD006E83-4501-47B5-BEEA-BA9326A3D630} = {A6FDF528-DB3B-4838-8D9D-F3E0F08DF97A} - {7299B336-9340-4E15-B0EE-B59C2770D7EE} = {8D3DAA2C-A035-47DC-92DE-A0DA501B32BF} - {32202E5E-02C2-48CA-9D8D-687146EB0232} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {6E92E509-834F-403C-A0B0-3B691F3C816D} = {32202E5E-02C2-48CA-9D8D-687146EB0232} - {1828D64E-F976-4B87-B37C-BD9E694E9482} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {382B91E4-9043-4261-BBE7-BEA9C0137C07} = {1828D64E-F976-4B87-B37C-BD9E694E9482} - {F7185339-B401-483F-8FB5-FBC9A1D4DBFC} = {AF835CF7-F63E-4667-A84D-298D4FF2E095} - {8E574EE1-3694-4905-B0FA-BEE599B5C0F9} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {4719C295-752C-4464-8A7D-151A1B8A37DD} = {8E574EE1-3694-4905-B0FA-BEE599B5C0F9} - {CC39E923-166C-43EB-BD80-6B89122CF7A5} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {C4535DDC-D848-4238-B99D-ED0C9767D64C} = {CC39E923-166C-43EB-BD80-6B89122CF7A5} - {5EFD2336-9236-4C29-9CFD-077E702D6ACD} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {AD45E9C7-D739-4513-8F01-3A6826E0F4FA} = {5EFD2336-9236-4C29-9CFD-077E702D6ACD} - {5771998F-DD44-4CEA-8B37-C2E90E5014AC} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {E0B6EFF9-41D8-4EDF-8303-5977D6637FF6} = {5771998F-DD44-4CEA-8B37-C2E90E5014AC} - {6EAC4719-E994-426D-87BD-6BB12FF17232} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {FF280BA1-B772-48AC-8110-065520F3B852} = {6EAC4719-E994-426D-87BD-6BB12FF17232} - {EA1FCF65-B230-4932-9164-85C2E39449BC} = {6EAC4719-E994-426D-87BD-6BB12FF17232} - {1F34FA6D-124F-42AD-BE5F-F31FF07B9E28} = {6EAC4719-E994-426D-87BD-6BB12FF17232} - {0DCC0BF3-FDFF-4AF7-A080-6A5D9213386F} = {6EAC4719-E994-426D-87BD-6BB12FF17232} - {9F730981-E25D-4857-B870-B98B0398688B} = {E148C898-1BFD-4F28-8940-583CC50F90DB} - {614740C2-6A5E-4F93-BD55-C3DF9B7EF33F} = {9F730981-E25D-4857-B870-B98B0398688B} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {ECEAECE7-49E5-4CBC-B84D-5FF82F2399FC} - EndGlobalSection -EndGlobal diff --git a/learn-dotnet.slnx b/learn-dotnet.slnx new file mode 100644 index 0000000..faf2e23 --- /dev/null +++ b/learn-dotnet.slnx @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 89b607b19aabfe0b05d0971a1e302b7d2b359920 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Thu, 5 Mar 2026 18:33:30 +0300 Subject: [PATCH 14/29] extension members demonstrate --- csharp/CSharp/CollectionExpressions.cs | 18 +++++++++++++++++- csharp/CSharp/ExtensionMembers.cs | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 csharp/CSharp/ExtensionMembers.cs diff --git a/csharp/CSharp/CollectionExpressions.cs b/csharp/CSharp/CollectionExpressions.cs index 14a72f7..9c61e17 100644 --- a/csharp/CSharp/CollectionExpressions.cs +++ b/csharp/CSharp/CollectionExpressions.cs @@ -50,4 +50,20 @@ public void SomeOtherMethod(string[] args) { _logger.LogInformation($"SomeOtherMethod is called with args: {string.Join(',', args)}"); } -} \ No newline at end of file + + public void ExtensionMembers() + { + IEnumerable empty = []; + IEnumerable numbers = [1, 2, 3]; + + _logger.LogInformation($"empty.IsEmpty: {empty.IsEmpty}"); + _logger.LogInformation($"numbers.IsEmpty: {numbers.IsEmpty}"); + + // "type" extension members (static-like on the extended type): + var combined = IEnumerable.Combine(numbers, [4, 5]); + _logger.LogInformation($"Combined: {string.Join(',', combined)}"); + + var identity = IEnumerable.Identity; + _logger.LogInformation($"Identity count: {identity.Count()}"); + } +} diff --git a/csharp/CSharp/ExtensionMembers.cs b/csharp/CSharp/ExtensionMembers.cs new file mode 100644 index 0000000..a34a08d --- /dev/null +++ b/csharp/CSharp/ExtensionMembers.cs @@ -0,0 +1,15 @@ +namespace CSharp; + +public static class ExtensionMembers +{ + extension(IEnumerable source) + { + public bool IsEmpty => !source.Any(); + } + + extension(IEnumerable) + { + public static IEnumerable Combine(IEnumerable first, IEnumerable second) => first.Concat(second); + public static IEnumerable Identity => []; + } +} \ No newline at end of file From bc5b2fa69f6ed01c3876370e93259b3679919c44 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Thu, 5 Mar 2026 18:41:24 +0300 Subject: [PATCH 15/29] more detailed examples --- csharp/CSharp/CollectionExpressions.cs | 13 ++++++------- csharp/CSharp/ExtensionMembers.cs | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/csharp/CSharp/CollectionExpressions.cs b/csharp/CSharp/CollectionExpressions.cs index 9c61e17..c2e783d 100644 --- a/csharp/CSharp/CollectionExpressions.cs +++ b/csharp/CSharp/CollectionExpressions.cs @@ -56,14 +56,13 @@ public void ExtensionMembers() IEnumerable empty = []; IEnumerable numbers = [1, 2, 3]; - _logger.LogInformation($"empty.IsEmpty: {empty.IsEmpty}"); - _logger.LogInformation($"numbers.IsEmpty: {numbers.IsEmpty}"); + _logger.LogInformation($"Extension property (instance-like): empty.IsEmpty on [] => {empty.IsEmpty}"); + _logger.LogInformation($"Extension property (instance-like): numbers.IsEmpty on [1,2,3] => {numbers.IsEmpty}"); - // "type" extension members (static-like on the extended type): var combined = IEnumerable.Combine(numbers, [4, 5]); - _logger.LogInformation($"Combined: {string.Join(',', combined)}"); + _logger.LogInformation($"Type extension method (static-like): IEnumerable.Combine() => {string.Join(',', combined)}"); - var identity = IEnumerable.Identity; - _logger.LogInformation($"Identity count: {identity.Count()}"); + var initialized = IEnumerable.Initialized; + _logger.LogInformation($"Type extension property (static-like): IEnumerable.Initialized count => {initialized.Count()}"); } -} +} \ No newline at end of file diff --git a/csharp/CSharp/ExtensionMembers.cs b/csharp/CSharp/ExtensionMembers.cs index a34a08d..ac2a024 100644 --- a/csharp/CSharp/ExtensionMembers.cs +++ b/csharp/CSharp/ExtensionMembers.cs @@ -10,6 +10,6 @@ public static class ExtensionMembers extension(IEnumerable) { public static IEnumerable Combine(IEnumerable first, IEnumerable second) => first.Concat(second); - public static IEnumerable Identity => []; + public static IEnumerable Initialized => []; } } \ No newline at end of file From 964b237df4f90ca5ae249c42a30ab6f58deb3788 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Thu, 5 Mar 2026 18:42:23 +0300 Subject: [PATCH 16/29] review --- csharp/CSharp/CollectionExpressions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/CSharp/CollectionExpressions.cs b/csharp/CSharp/CollectionExpressions.cs index c2e783d..02fd9fc 100644 --- a/csharp/CSharp/CollectionExpressions.cs +++ b/csharp/CSharp/CollectionExpressions.cs @@ -56,8 +56,8 @@ public void ExtensionMembers() IEnumerable empty = []; IEnumerable numbers = [1, 2, 3]; - _logger.LogInformation($"Extension property (instance-like): empty.IsEmpty on [] => {empty.IsEmpty}"); - _logger.LogInformation($"Extension property (instance-like): numbers.IsEmpty on [1,2,3] => {numbers.IsEmpty}"); + _logger.LogInformation($"Extension property (instance-like): empty.IsEmpty => {empty.IsEmpty}"); + _logger.LogInformation($"Extension property (instance-like): numbers.IsEmpty => {numbers.IsEmpty}"); var combined = IEnumerable.Combine(numbers, [4, 5]); _logger.LogInformation($"Type extension method (static-like): IEnumerable.Combine() => {string.Join(',', combined)}"); From fe0e025d57b94e8215947074116d7d26987e6927 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Fri, 6 Mar 2026 10:47:39 +0300 Subject: [PATCH 17/29] init 'issue/dotnet-10/field-keyword' --- csharp/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/README.md b/csharp/README.md index 36cdee7..708cec8 100644 --- a/csharp/README.md +++ b/csharp/README.md @@ -9,3 +9,4 @@ What we have learned and implemented so far are the following. - Different Params type usage - Encoding Decoding - Lambda Parameters +- PropertiesAndFields \ No newline at end of file From b89cacd49be6f43e7d242a1f563520f202897da0 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:21:10 +0300 Subject: [PATCH 18/29] demonstrate field keyword --- csharp/CSharp/Program.cs | 6 +++++- csharp/CSharp/PropertiesAndFields.cs | 18 ++++++++++++++++++ csharp/README.md | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 csharp/CSharp/PropertiesAndFields.cs diff --git a/csharp/CSharp/Program.cs b/csharp/CSharp/Program.cs index 2fb469f..bfc8458 100644 --- a/csharp/CSharp/Program.cs +++ b/csharp/CSharp/Program.cs @@ -8,6 +8,7 @@ serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); +serviceCollection.AddSingleton(); serviceCollection.AddLogging(options => { @@ -21,6 +22,7 @@ var encodingDecoding = serviceProvider.GetRequiredService(); var lambdaParameters = serviceProvider.GetRequiredService(); var @params = serviceProvider.GetRequiredService(); +var propertiesAndFields = serviceProvider.GetRequiredService(); @params.Use(); @@ -32,4 +34,6 @@ lambdaParameters.ParamsArrayParameters(); lambdaParameters.NewAcceptedBehavior(); -encodingDecoding.RunShowCases(); \ No newline at end of file +encodingDecoding.RunShowCases(); + +propertiesAndFields.FieldKeyword(); \ No newline at end of file diff --git a/csharp/CSharp/PropertiesAndFields.cs b/csharp/CSharp/PropertiesAndFields.cs new file mode 100644 index 0000000..bed8e41 --- /dev/null +++ b/csharp/CSharp/PropertiesAndFields.cs @@ -0,0 +1,18 @@ +using Microsoft.Extensions.Logging; + +namespace CSharp; + +public class PropertiesAndFields(ILogger _logger) +{ + string _filed = "field"; + + public string WithOutFieldKeyword { get => _filed; set => _filed = value; } + public string WithFieldKeyword { get; set => field = value.Trim(); } = "WithField"; + + public void FieldKeyword() + { + _logger.LogInformation($"_field => '{_filed}'"); + _logger.LogInformation($"WithOutFieldKeyword => '{WithOutFieldKeyword}'"); + _logger.LogInformation($"WithFieldKeyword => '{WithFieldKeyword}'"); + } +} diff --git a/csharp/README.md b/csharp/README.md index 708cec8..3af2307 100644 --- a/csharp/README.md +++ b/csharp/README.md @@ -9,4 +9,4 @@ What we have learned and implemented so far are the following. - Different Params type usage - Encoding Decoding - Lambda Parameters -- PropertiesAndFields \ No newline at end of file +- Properties and fields \ No newline at end of file From 5e0a8ac5fe1313d9c6899d24382910b3aac40033 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:44:16 +0300 Subject: [PATCH 19/29] demonstrate implicit conversions --- csharp/CSharp/CollectionExpressions.cs | 13 +++++++++++++ csharp/CSharp/Program.cs | 1 + 2 files changed, 14 insertions(+) diff --git a/csharp/CSharp/CollectionExpressions.cs b/csharp/CSharp/CollectionExpressions.cs index 02fd9fc..e26f915 100644 --- a/csharp/CSharp/CollectionExpressions.cs +++ b/csharp/CSharp/CollectionExpressions.cs @@ -34,6 +34,19 @@ public void CollectionInitialization() _logger.LogInformation($"Array initialization with spread element and members: {string.Join(',', anotherIntCollection)}"); } + public void Conversions() + { + int[] numbers = [1, 2, 3]; + + // T[] -> Span + Span spanNumbers = numbers; + _logger.LogInformation($"Implicit Conversion int[] -> span: {string.Join(',', spanNumbers.ToArray())}"); + + // T[] -> ReadOnlySpan + ReadOnlySpan readOnlyNumbers = numbers; + _logger.LogInformation($"Implicit Conversion int[] -> ReadOnlySpan: {string.Join(',', readOnlyNumbers.ToArray())}"); + } + public void CallMethods() { SomeMethod("arg1", "arg2", "arg3"); diff --git a/csharp/CSharp/Program.cs b/csharp/CSharp/Program.cs index bfc8458..2f2df25 100644 --- a/csharp/CSharp/Program.cs +++ b/csharp/CSharp/Program.cs @@ -28,6 +28,7 @@ collectionExpressions.EmptyCollectionInitialization(); collectionExpressions.CollectionInitialization(); +collectionExpressions.Conversions(); collectionExpressions.CallMethods(); lambdaParameters.OptionalParameters(); From 22c6bb36db63fc447f5a669714bc6516fb826ddf Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Fri, 6 Mar 2026 13:32:03 +0300 Subject: [PATCH 20/29] demonstrate parameter modifiers --- csharp/CSharp/LambdaParameters.cs | 12 +- csharp/CSharp/Program.cs | 1 + csharp/CSharp/PropertiesAndFields.cs | 2 +- dotnet-10-research-notes.md | 163 --------------------------- 4 files changed, 13 insertions(+), 165 deletions(-) diff --git a/csharp/CSharp/LambdaParameters.cs b/csharp/CSharp/LambdaParameters.cs index 7c57a00..c672608 100644 --- a/csharp/CSharp/LambdaParameters.cs +++ b/csharp/CSharp/LambdaParameters.cs @@ -2,7 +2,7 @@ namespace CSharp; -public class LambdaParameters(ILogger _logger) +public class LambdaParameters(ILogger _logger) { public void OptionalParameters() { @@ -32,4 +32,14 @@ void Params(params int[] values) { } optional(); @params(); } + + private delegate bool TryParse(string text, out T result); + + public void ParameterModifiersWithoutTypes() + { + // Lambdas support modifiers (ref/in/out/scoped/ref readonly) without explicit parameter types when the target delegate type is known + TryParse parse = (text, out result) => int.TryParse(text, out result); + + _logger.LogInformation($"(text, out result) => int.TryParse: ok={parse("42", out int value)}, result={value}"); + } } \ No newline at end of file diff --git a/csharp/CSharp/Program.cs b/csharp/CSharp/Program.cs index 2f2df25..8c98059 100644 --- a/csharp/CSharp/Program.cs +++ b/csharp/CSharp/Program.cs @@ -34,6 +34,7 @@ lambdaParameters.OptionalParameters(); lambdaParameters.ParamsArrayParameters(); lambdaParameters.NewAcceptedBehavior(); +lambdaParameters.ParameterModifiersWithoutTypes(); encodingDecoding.RunShowCases(); diff --git a/csharp/CSharp/PropertiesAndFields.cs b/csharp/CSharp/PropertiesAndFields.cs index bed8e41..6261d4f 100644 --- a/csharp/CSharp/PropertiesAndFields.cs +++ b/csharp/CSharp/PropertiesAndFields.cs @@ -15,4 +15,4 @@ public void FieldKeyword() _logger.LogInformation($"WithOutFieldKeyword => '{WithOutFieldKeyword}'"); _logger.LogInformation($"WithFieldKeyword => '{WithFieldKeyword}'"); } -} +} \ No newline at end of file diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md index afd3a3e..c3aa26a 100644 --- a/dotnet-10-research-notes.md +++ b/dotnet-10-research-notes.md @@ -1,97 +1,6 @@ # .NET 10 Research Notes -## Migration Tasks - -> [!INFO] This task are temp - -- [ ] install dotnet 10 -- [ ] upgrade dotnet version to `10` -- [ ] upgrade c# version to `14` -- [ ] make sure packages fine with dotnet 10 -- Opportunistic Improvements - - [ ] Use `CompareOptions.NumericOrdering` property of the `StringComparer` - object if it will make things easier - - [ ] At first glance, it didn't seem necessary, but if needed, it looks like - description support has been added to `ProducesAttribute`, - `ProducesResponseTypeAttribute`, and `ProducesDefaultResponseTypeAttribute` - - [ ] Use `RedirectHttpResult.IsLocalUrl` in places that check whether the URL - redirects to the locale or externally - - [ ] Use if necessary, the `field` keyword in properties - - [ ] Now allows `nameof` for unbound generics. If there were different - approaches previously because it wasn't allowed, these can be simplified - - [ ] The partial constructor feature now supported. Use it if we need to - - probably, the analyzer will already warn you, but just in case; - - [ ] use implicit `Span` conversions to array - - [ ] use simple lambda parameters with modifiers - - [ ] use Null-Conditional assignment - - do if okay after learn - - [ ] if it is really necessary, use the validation attributes in response - records - - [ ] if necessary, edit the response of unhandled errors with - `IProblemDetailsService` -- Required Migrations - - [ ] use `.slnx` instead of `.sln` - - [ ] use extension members - - Property extensions will be used for those that do not take parameters and - for specifying layer builders. exp: `configure.Ui.ComponentPresets(...)` - - if okay after learn - - [ ] use `Microsoft Testing Platform` for testing -- Troubleshooting & Pitfalls(You should also test the tasks that can be checked - to be sure) - - `HttpContent` now returns `BrowserHttpReadStream` instead of `MemoryStream` - - The warning level for audits has been raised in `dotnet restore`. If the - error encountered cannot be resolved, the warning level can be lowered in - `Directory.Build.props` or the relevant warning can be ignored - - Validation APIs moved to `Microsoft.Extensions.Validation` - - If you encounter any issues with OpenAPI, check [here](https://github.com/microsoft/OpenAPI.NET/blob/main/docs/upgrade-guide-2.md) - - [ ] If `dotnet restore` is waiting for user input, it should be set to - `--interactive false` - - [ ] If you encounter an error or receive incorrect results when obtaining - coverage, you may need to set `EnableDynamicNativeInstrumentation` to `true` - - [ ] Now, in form post actions, `nullable` fields are automatically set to - null when they receive an empty string - -## Libraries - -### Numeric ordering for string comparison - -stringlerin sonuna göre sıralama yapıyor. - -```csharp -StringComparer numericStringComparer = StringComparer.Create(CultureInfo.CurrentCulture, CompareOptions.NumericOrdering); - -foreach (string os in new[] { "Windows 11", "Windows 10", "Windows 8" }.Order(numericStringComparer)) -{ - Console.WriteLine(os); -} - -// Output: -// Windows 8 -// Windows 10 -// Windows 11 -``` - -This option isn't valid for the following index-based string operations: -IndexOf, LastIndexOf, StartsWith, EndsWith, IsPrefix, and IsSuffix. - -## Networking - -### Streaming HTTP responses enabled by default in browser HTTP clients - -The [HttpContent](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent) no longer contains a [MemoryStream](https://learn.microsoft.com/en-us/dotnet/api/system.io.memorystream). Instead, [HttpContent.ReadAsStreamAsync](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync) returns a `BrowserHttpReadStream`, which does not support synchronous operations. - -```csharp -var response = await httpClient.GetAsync("https://example.com"); -var contentStream = await response.Content.ReadAsStreamAsync(); // Returns BrowserHttpReadStream instead of MemoryStream -``` - -## SDK - -### SLNX file format - -sln dosyaları slnx olacak - ### Support for Microsoft Testing Platform in dotnet test dotnet test natively supports Microsoft.Testing.Platform. To enable this @@ -107,11 +16,6 @@ feature, add the following configuration to your global.json file: [MTP](https://learn.microsoft.com/en-us/dotnet/core/testing/microsoft-testing-platform-intro) -### .NET CLI `--interactive` defaults to `true` in user scenarios - -bu interactive default olarak true yapılmış. `dotnet restore` tarafında bir sorun çıkarsa -bundan kaynaklı olabilir. `--interactive false` şeklinde verilerek tekrar kapatılabilir - ### Code coverage EnableDynamicNativeInstrumentation defaults to false büyük ihtimalle bizi etkilemeyecek ama depend edilen kütüphanelerle ilgili problem olursa diye @@ -262,64 +166,6 @@ için otomatik olarak log ve telemetry yazılmıyor ## C# 14 -### Extension members - -yeni extension yazma yöntemleri geldi -bu syntax a geçilecek - -```csharp -public static class Enumerable -{ - // Extension block - extension(IEnumerable source) // extension members for IEnumerable - { - // Extension property: - public bool IsEmpty => !source.Any(); - - // Extension method: - public IEnumerable Where(Func predicate) { ... } - } - - // extension block, with a receiver type only - extension(IEnumerable) // static extension members for IEnumerable - { - // static extension method: - public static IEnumerable Combine(IEnumerable first, IEnumerable second) { ... } - - // static extension property: - public static IEnumerable Identity => Enumerable.Empty(); - - // static user defined operator: - public static IEnumerable operator + (IEnumerable left, IEnumerable right) => left.Concat(right); - } -} -``` - -### `field` - -artık field tanımlamaya gerek yok - -```csharp -public string Name -{ - get; - set => field = value ?? throw new ArgumentNullException(nameof(value)); -} -``` - -### Implicit Span Conversions - -Span `` ve ReadOnlySpan `` için, ReadOnlySpan ``, Span `` ve T[] türlerine -implicit cast gelmiş - -```csharp -int[] array = new[] { 1, 2, 3 }; -ReadOnlySpan ros = array; - -void Process(ReadOnlySpan data) { } -Process(array); -``` - ### `nameof` Unbound Generic Types aşağıdaki işlemlere izin veriliyormuş @@ -329,15 +175,6 @@ nameof(List<>) nameof(Dictionary<,>) ``` -### Simple lambda parameters with modifiers - -scoped, ref, in, out, or ref readonly gibi lambda expression parametrelerinde -type belirtme biraz daha hafiflemiş. bunlarda analyzerlar önerileri veriyor zaten - -```csharp -TryParse parse2 = (string text, out int result) => Int32.TryParse(text, out result); -``` - ### partial members artık instance constructors ve events partial olabiliyormuş From ce57220cc11c3c19491620b1a7621cc3e52f2d96 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Fri, 6 Mar 2026 15:01:44 +0300 Subject: [PATCH 21/29] demonstrate nullable assignments --- csharp/CSharp/Assignments.cs | 25 ++++++ csharp/CSharp/Program.cs | 4 + csharp/README.md | 1 + dotnet-10-research-notes.md | 151 ----------------------------------- 4 files changed, 30 insertions(+), 151 deletions(-) create mode 100644 csharp/CSharp/Assignments.cs diff --git a/csharp/CSharp/Assignments.cs b/csharp/CSharp/Assignments.cs new file mode 100644 index 0000000..6c6a435 --- /dev/null +++ b/csharp/CSharp/Assignments.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Logging; + +namespace CSharp; + +public class Assignments(ILogger _logger) +{ + public Data? NullableData { get; set; } = default; + + public void NullableAssignment() + { + NullableData?.Value = "test"; + + _logger.LogInformation($"Before data is created, NullableData: {NullableData}"); + + NullableData = new(); + NullableData?.Value = "test"; + + _logger.LogInformation($"After data is created, NullableData: {NullableData} - Value: {NullableData?.Value}"); + } + + public class Data + { + public string? Value { get; set; } + } +} diff --git a/csharp/CSharp/Program.cs b/csharp/CSharp/Program.cs index 8c98059..de7eb49 100644 --- a/csharp/CSharp/Program.cs +++ b/csharp/CSharp/Program.cs @@ -4,6 +4,7 @@ var serviceCollection = new ServiceCollection(); +serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -18,6 +19,7 @@ var serviceProvider = serviceCollection.BuildServiceProvider(); +var assignments = serviceProvider.GetRequiredService(); var collectionExpressions = serviceProvider.GetRequiredService(); var encodingDecoding = serviceProvider.GetRequiredService(); var lambdaParameters = serviceProvider.GetRequiredService(); @@ -26,6 +28,8 @@ @params.Use(); +assignments.NullableAssignment(); + collectionExpressions.EmptyCollectionInitialization(); collectionExpressions.CollectionInitialization(); collectionExpressions.Conversions(); diff --git a/csharp/README.md b/csharp/README.md index 3af2307..d23a3b9 100644 --- a/csharp/README.md +++ b/csharp/README.md @@ -5,6 +5,7 @@ projects. What we have learned and implemented so far are the following. +- Assignments - Collection expressions - Different Params type usage - Encoding Decoding diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md index c3aa26a..1495b3e 100644 --- a/dotnet-10-research-notes.md +++ b/dotnet-10-research-notes.md @@ -16,48 +16,6 @@ feature, add the following configuration to your global.json file: [MTP](https://learn.microsoft.com/en-us/dotnet/core/testing/microsoft-testing-platform-intro) -### Code coverage EnableDynamicNativeInstrumentation defaults to false - -büyük ihtimalle bizi etkilemeyecek ama depend edilen kütüphanelerle ilgili problem olursa diye -not olarak ekliyorum. - -coverage collect te EnableDynamicNativeInstrumentation false yapılmış. native araçlardan -coverage almada sorun çıkarıyor bu flag - -### dotnet restore audits transitive packages - -audit warningleri default olarak seviye atlatılmış. bizde warningler error olarak gösterildiğinden -restorelarda sorun yaratabilir. - -```xml - - - - -yada - - - NU1901;NU1902;NU1903;NU1904;$(WarningsNotAsErrors) - -``` - -## ASP.NET - -### Treating empty string in form post as null for nullable value types - -When using the [FromForm] attribute - -```csharp -app.MapPost("/todo", ([FromForm] Todo todo) => TypedResults.Ok(todo)); - -... - -public class Todo -{ - public DateOnly? DueDate { get; set; } // Empty strings map to `null` -} -``` - ### Validation support in Minimal APIs `AddValidation` ile response model'de eklenen attributes'lar ile validasyon yapılabiliyor @@ -86,112 +44,3 @@ https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.iproblemd The validation APIs have moved to the `Microsoft.Extensions.Validation` namespace and NuGet package. - -### OpenAPI - -#### Response description on ProducesResponseType for API controllers - -The `ProducesAttribute`, `ProducesResponseTypeAttribute`, and -`ProducesDefaultResponseTypeAttribute` now accept an optional string parameter, -`Description`, that sets the description of the response: - -```C# -[HttpGet(Name = "GetWeatherForecast")] -[ProducesResponseType>(StatusCodes.Status200OK, - Description = "The weather forecast for the next 5 days.")] -public IEnumerable Get() -{ -``` - -#### Support for `IOpenApiDocumentProvider` in the DI container - -bu servis OpenAPI dokümanını kod içinden programatik olarak alabilmeyi sağlıyor - -#### Use HTTP Method Object Instead of Enum - -```csharp -// Before (1.6) -OpenApiOperation operation = new OpenApiOperation -{ - HttpMethod = OperationType.Get -}; - -// After (2.0) -OpenApiOperation operation = new OpenApiOperation -{ - HttpMethod = new HttpMethod("GET") // or HttpMethod.Get -}; -``` - -[daha fazla 2.0 değişikliği için](https://github.com/microsoft/OpenAPI.NET/blob/main/docs/upgrade-guide-2.md) - -### Authentication and authorization - -#### Avoid cookie login redirects for known API endpoints - -sanırım bu bizi ilgilendirmiyor biz login e redirect etmiyoruz zaten ama yapılan -şeyi yinede yazayım: -Artık bilinen API endpoint'lerine yapılan yetkisiz istekler login sayfasına -yönlendirme yerine doğrudan 401 ve 403 döndürüyor. - -### Diğerleri - -#### Support for the .localhost Top-Level Domain - -```json -{ - "profiles": { - "https": { - "applicationUrl": "https://myapp.dev.localhost:7099;http://myapp.dev.localhost:5036" - } - } -} -``` - -> [!NOTE] -> -> After installing .NET 10 SDK Preview 7, trust the new developer certificate by -> running dotnet dev-certs https --trust at the command line to ensure your -> system is configured to trust the new certificate. - -#### Detect if URL is local using `RedirectHttpResult.IsLocalUrl` - -`RedirectHttpResult.IsLocalUrl` diye bir helper gelmiş. url veriyorsun oradaki -redirecturl locale e mi gidecek diye bakıyor. locale se true dönüyor. - -#### Exception diagnostics are suppressed when IExceptionHandler.TryHandleAsync returns true - -`IExceptionHandler` ile exception'ları handle ettiğinde(true döndüğünde) artık o exception -için otomatik olarak log ve telemetry yazılmıyor - -## C# 14 - -### `nameof` Unbound Generic Types - -aşağıdaki işlemlere izin veriliyormuş - -```csharp -nameof(List<>) -nameof(Dictionary<,>) -``` - -### partial members - -artık instance constructors ve events partial olabiliyormuş - -### User-Defined Compound Assignment - -sanırım eskiden +=, -=, *= gibi operatorleri kendin yazamıyordun. artık -yazılabiliyor gibi - -tam olarak hangilerine izin var tam anlamadım https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-14.0/user-defined-compound-assignment - -### Null-Conditional Assignment - -atamalarda if ile not null kontrolüne gerek kalmamış - -```csharp -customer?.Order = GetCurrentOrder(); -``` - -ama +=, -= falan desteklemiyor From 080e195c979dd3c23d93625655003e7fc7d860ed Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Fri, 6 Mar 2026 15:03:14 +0300 Subject: [PATCH 22/29] rename method --- csharp/CSharp/Assignments.cs | 2 +- csharp/CSharp/Program.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/CSharp/Assignments.cs b/csharp/CSharp/Assignments.cs index 6c6a435..9505879 100644 --- a/csharp/CSharp/Assignments.cs +++ b/csharp/CSharp/Assignments.cs @@ -6,7 +6,7 @@ public class Assignments(ILogger _logger) { public Data? NullableData { get; set; } = default; - public void NullableAssignment() + public void NullConditional() { NullableData?.Value = "test"; diff --git a/csharp/CSharp/Program.cs b/csharp/CSharp/Program.cs index de7eb49..ac256b3 100644 --- a/csharp/CSharp/Program.cs +++ b/csharp/CSharp/Program.cs @@ -28,7 +28,7 @@ @params.Use(); -assignments.NullableAssignment(); +assignments.NullConditional(); collectionExpressions.EmptyCollectionInitialization(); collectionExpressions.CollectionInitialization(); From ec39e9170d7731c7201032aca780b7573ada7baa Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Fri, 6 Mar 2026 15:05:13 +0300 Subject: [PATCH 23/29] fix format --- csharp/CSharp/Assignments.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/CSharp/Assignments.cs b/csharp/CSharp/Assignments.cs index 9505879..c7bd3db 100644 --- a/csharp/CSharp/Assignments.cs +++ b/csharp/CSharp/Assignments.cs @@ -22,4 +22,4 @@ public class Data { public string? Value { get; set; } } -} +} \ No newline at end of file From 4e1eef61bdc7f976ec102f13c7aa021ab66531ef Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Fri, 6 Mar 2026 17:01:18 +0300 Subject: [PATCH 24/29] init 'issue/dotnet-10/mtp' --- .gitignore | 3 --- Directory.Build.props | 1 + global.json | 5 +++++ unit-testing/UnitTesting/UnitTesting.csproj | 6 ++---- 4 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 global.json diff --git a/.gitignore b/.gitignore index 894a117..2b1cbbb 100644 --- a/.gitignore +++ b/.gitignore @@ -18,9 +18,6 @@ bld/ # visual studio code .vscode/ -# dotnet sdk -global.json - # generated file **/Generated/**/*.cs **/.benchmark/** diff --git a/Directory.Build.props b/Directory.Build.props index 5f334af..9e894be 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -10,6 +10,7 @@ true true true + true diff --git a/global.json b/global.json new file mode 100644 index 0000000..3140116 --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "test": { + "runner": "Microsoft.Testing.Platform" + } +} diff --git a/unit-testing/UnitTesting/UnitTesting.csproj b/unit-testing/UnitTesting/UnitTesting.csproj index 89f79ba..64dbd6b 100644 --- a/unit-testing/UnitTesting/UnitTesting.csproj +++ b/unit-testing/UnitTesting/UnitTesting.csproj @@ -1,6 +1,7 @@ + Exe false true @@ -8,6 +9,7 @@ + @@ -15,10 +17,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - From 22e4bd687a29effa2eac96e1f8ee15d28bd10efb Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Fri, 6 Mar 2026 17:06:16 +0300 Subject: [PATCH 25/29] fix typo --- csharp/CSharp/PropertiesAndFields.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/csharp/CSharp/PropertiesAndFields.cs b/csharp/CSharp/PropertiesAndFields.cs index 6261d4f..c8f0338 100644 --- a/csharp/CSharp/PropertiesAndFields.cs +++ b/csharp/CSharp/PropertiesAndFields.cs @@ -4,14 +4,14 @@ namespace CSharp; public class PropertiesAndFields(ILogger _logger) { - string _filed = "field"; + string _field = "field"; - public string WithOutFieldKeyword { get => _filed; set => _filed = value; } + public string WithOutFieldKeyword { get => _field; set => _field = value; } public string WithFieldKeyword { get; set => field = value.Trim(); } = "WithField"; public void FieldKeyword() { - _logger.LogInformation($"_field => '{_filed}'"); + _logger.LogInformation($"_field => '{_field}'"); _logger.LogInformation($"WithOutFieldKeyword => '{WithOutFieldKeyword}'"); _logger.LogInformation($"WithFieldKeyword => '{WithFieldKeyword}'"); } From de2ea3c2cb9afa66b571576d0bfc1b933bb257e3 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Fri, 6 Mar 2026 18:09:22 +0300 Subject: [PATCH 26/29] add coverage --- .github/workflows/project-regular-checks.yml | 8 +++++++- .gitignore | 1 + Directory.Packages.props | 2 ++ unit-testing/UnitTesting/UnitTesting.csproj | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/project-regular-checks.yml b/.github/workflows/project-regular-checks.yml index 168a25f..11282ce 100644 --- a/.github/workflows/project-regular-checks.yml +++ b/.github/workflows/project-regular-checks.yml @@ -23,4 +23,10 @@ jobs: - name: Build Solution run: dotnet build --no-restore -c Release - name: Run Tests - run: dotnet test + run: | + dotnet test \ + --coverage \ + --coverage-output-format cobertura \ + --coverage-output .coverage/coverage.cobertura.xml \ + --report-trx \ + --results-directory .coverage diff --git a/.gitignore b/.gitignore index 2b1cbbb..fd954be 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ bld/ **/Generated/**/*.cs **/.benchmark/** **/**/*.dll +.coverage/ # generated schemas **/*.schema.json diff --git a/Directory.Packages.props b/Directory.Packages.props index a36a391..a17c949 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -27,6 +27,8 @@ + + diff --git a/unit-testing/UnitTesting/UnitTesting.csproj b/unit-testing/UnitTesting/UnitTesting.csproj index 64dbd6b..56d1cd7 100644 --- a/unit-testing/UnitTesting/UnitTesting.csproj +++ b/unit-testing/UnitTesting/UnitTesting.csproj @@ -10,6 +10,7 @@ + From 089a0bcd2d95b95efd16f877d14af38fd629c534 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Sat, 7 Mar 2026 12:57:44 +0300 Subject: [PATCH 27/29] remove empty braces --- model-binders/ModelBinders/IQuery.cs | 4 +--- model-binders/ModelBinders/ModelOne.cs | 4 +--- model-binders/ModelBinders/ModelTwo.cs | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/model-binders/ModelBinders/IQuery.cs b/model-binders/ModelBinders/IQuery.cs index b5f0f58..ab0c2c2 100644 --- a/model-binders/ModelBinders/IQuery.cs +++ b/model-binders/ModelBinders/IQuery.cs @@ -1,5 +1,3 @@ namespace ModelBinders; -public interface IQuery : IDictionary -{ -} \ No newline at end of file +public interface IQuery : IDictionary; \ No newline at end of file diff --git a/model-binders/ModelBinders/ModelOne.cs b/model-binders/ModelBinders/ModelOne.cs index 12d3181..f355afd 100644 --- a/model-binders/ModelBinders/ModelOne.cs +++ b/model-binders/ModelBinders/ModelOne.cs @@ -6,6 +6,4 @@ public class ModelOne(Guid _id, string _name) public string Name => _name; } -public class ModelOnes : Dictionary, IQuery -{ -} \ No newline at end of file +public class ModelOnes : Dictionary, IQuery; \ No newline at end of file diff --git a/model-binders/ModelBinders/ModelTwo.cs b/model-binders/ModelBinders/ModelTwo.cs index 942186f..823054c 100644 --- a/model-binders/ModelBinders/ModelTwo.cs +++ b/model-binders/ModelBinders/ModelTwo.cs @@ -6,6 +6,4 @@ public class ModelTwo(Guid _id, string _name) public string Name => _name; } -public class ModelTwos : Dictionary, IQuery -{ -} \ No newline at end of file +public class ModelTwos : Dictionary, IQuery; \ No newline at end of file From f72db84dc82956f2406feb2850c080f8a1130b7e Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Mon, 9 Mar 2026 11:30:33 +0300 Subject: [PATCH 28/29] init 'issue/dotnet-10/final-touches' --- dotnet-10-research-notes.md | 46 ------------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 dotnet-10-research-notes.md diff --git a/dotnet-10-research-notes.md b/dotnet-10-research-notes.md deleted file mode 100644 index 1495b3e..0000000 --- a/dotnet-10-research-notes.md +++ /dev/null @@ -1,46 +0,0 @@ - -# .NET 10 Research Notes - -### Support for Microsoft Testing Platform in dotnet test - -dotnet test natively supports Microsoft.Testing.Platform. To enable this -feature, add the following configuration to your global.json file: - -```csharp -{ - "test": { - "runner": "Microsoft.Testing.Platform" - } -} -``` - -[MTP](https://learn.microsoft.com/en-us/dotnet/core/testing/microsoft-testing-platform-intro) - -### Validation support in Minimal APIs - -`AddValidation` ile response model'de eklenen attributes'lar ile validasyon yapılabiliyor - -```csharp -app.MapPost("/products", - ([EvenNumber(ErrorMessage = "Product ID must be even")] int productId, [Required] string name) - => TypedResults.Ok(productId)) - .DisableValidation(); -//****** -public record Product( - [Required] string Name, - [Range(1, 1000)] int Quantity); -``` - -### `IProblemDetailsService` - -bir örnek yap -Defines a type that provide functionality to create a ProblemDetails response. - -Bu 7'den sonra da varmış. Kullanmamışız. Ben yinede ekliyim belki şimdi bazı şeyleri kolaylayabilir. - -https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.iproblemdetailsservice?view=aspnetcore-10.0 - -### Validation APIs moved to `Microsoft.Extensions.Validation` - -The validation APIs have moved to the `Microsoft.Extensions.Validation` -namespace and NuGet package. From 98bf241177f416380a87e12f028a637b7fac17f0 Mon Sep 17 00:00:00 2001 From: Sefer Mirza <36925434+SeferMirza@users.noreply.github.com> Date: Mon, 9 Mar 2026 11:31:11 +0300 Subject: [PATCH 29/29] update versions on actions --- .github/workflows/project-regular-checks.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/project-regular-checks.yml b/.github/workflows/project-regular-checks.yml index 11282ce..b61ad89 100644 --- a/.github/workflows/project-regular-checks.yml +++ b/.github/workflows/project-regular-checks.yml @@ -11,11 +11,11 @@ jobs: name: Build & Test runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: - dotnet-version: 9 + dotnet-version: 10 - name: Restore Dependencies run: dotnet restore - name: Format Solution