Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
117c4d7
init 'issue/dotnet-10/research'
SeferMirza Mar 3, 2026
6da5872
add research notes
SeferMirza Mar 3, 2026
90575c9
add more research notes
SeferMirza Mar 3, 2026
7752972
add last update notes
SeferMirza Mar 3, 2026
d227384
add new task
SeferMirza Mar 3, 2026
79d0b00
add migration notes
SeferMirza Mar 4, 2026
2c1c1cf
add migration tasks
SeferMirza Mar 4, 2026
041c27f
edit document
SeferMirza Mar 4, 2026
be891f3
add note
SeferMirza Mar 4, 2026
68ba99c
Merge pull request #41 from SeferMirza/issue/dotnet-10/research
SeferMirza Mar 5, 2026
d91b28f
init 'issue/dotnet-10/extension-members'
SeferMirza Mar 5, 2026
063ae1b
fix build
SeferMirza Mar 5, 2026
4d7baed
make inline security adding
SeferMirza Mar 5, 2026
c700822
sln migrate
SeferMirza Mar 5, 2026
89b607b
extension members demonstrate
SeferMirza Mar 5, 2026
bc5b2fa
more detailed examples
SeferMirza Mar 5, 2026
964b237
review
SeferMirza Mar 5, 2026
46fecce
Merge pull request #43 from SeferMirza/issue/dotnet-10/extension-members
SeferMirza Mar 6, 2026
fe0e025
init 'issue/dotnet-10/field-keyword'
SeferMirza Mar 6, 2026
b89cacd
demonstrate field keyword
SeferMirza Mar 6, 2026
5e0a8ac
demonstrate implicit conversions
SeferMirza Mar 6, 2026
22c6bb3
demonstrate parameter modifiers
SeferMirza Mar 6, 2026
ce57220
demonstrate nullable assignments
SeferMirza Mar 6, 2026
080e195
rename method
SeferMirza Mar 6, 2026
ec39e91
fix format
SeferMirza Mar 6, 2026
563bfc0
Merge pull request #44 from SeferMirza/issue/dotnet-10/field-keyword
SeferMirza Mar 6, 2026
4e1eef6
init 'issue/dotnet-10/mtp'
SeferMirza Mar 6, 2026
22e4bd6
fix typo
SeferMirza Mar 6, 2026
de2ea3c
add coverage
SeferMirza Mar 6, 2026
089a0bc
remove empty braces
SeferMirza Mar 7, 2026
9a0387f
Merge pull request #45 from SeferMirza/issue/dotnet-10/mtp
cihandeniz Mar 7, 2026
f72db84
init 'issue/dotnet-10/final-touches'
SeferMirza Mar 9, 2026
98bf241
update versions on actions
SeferMirza Mar 9, 2026
af2e749
Merge pull request #46 from SeferMirza/issue/dotnet-10/final-touches
SeferMirza Mar 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions .github/workflows/project-regular-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@ 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
run: dotnet format --no-restore --verify-no-changes --verbosity diagnostic
- 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
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ bld/
# visual studio code
.vscode/

# dotnet sdk
global.json

# generated file
**/Generated/**/*.cs
**/.benchmark/**
**/**/*.dll
.coverage/

# generated schemas
**/*.schema.json
Expand Down
5 changes: 3 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
<Project>

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>13.0</LangVersion>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>14.0</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AnalysisModeStyle>All</AnalysisModeStyle>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<EnableNUnitRunner>true</EnableNUnitRunner>
</PropertyGroup>

<ItemGroup>
Expand Down
54 changes: 28 additions & 26 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,38 @@
</PropertyGroup>

<ItemGroup>
<PackageVersion Include="Aspire.Hosting.AppHost" Version="9.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Localization" Version="2.3.0" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="9.1.0" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="9.0.0" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.11.1" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.11.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.11.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.11.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.11.0" />
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="9.0.1" />
<PackageVersion Include="Aspire.Hosting.AppHost" Version="13.1.2" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="10.3.0" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="10.3.0" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.15.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.15.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.15.0" />
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8" />
<PackageVersion Include="coverlet.collector" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.3" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="9.1.0" />
<PackageVersion Include="Microsoft.NET.Build.Containers" Version="8.0.302" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.3" />
<PackageVersion Include="Microsoft.OpenApi" Version="3.3.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.3" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.3" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="10.0.3" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="10.3.0" />
<PackageVersion Include="Microsoft.NET.Build.Containers" Version="10.0.103" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
<PackageVersion Include="Microsoft.Testing.Extensions.CodeCoverage" Version="18.5.2" />
<PackageVersion Include="Microsoft.Testing.Extensions.TrxReport" Version="2.1.0" />
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="NUnit" Version="4.3.2" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageVersion Include="NUnit.Analyzers" Version="4.6.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="NUnit" Version="4.5.0" />
<PackageVersion Include="NUnit3TestAdapter" Version="6.1.0" />
<PackageVersion Include="NUnit.Analyzers" Version="4.11.2" />
<PackageVersion Include="Shouldly" Version="4.3.0" />
<PackageVersion Include="StyleCop.Analyzers.Unstable" Version="1.2.0.556" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="7.2.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="10.1.4" />
</ItemGroup>

</Project>
6 changes: 3 additions & 3 deletions aspire/Aspire.ServiceDefaults/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});

Expand Down Expand Up @@ -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;
Expand Down
25 changes: 25 additions & 0 deletions csharp/CSharp/Assignments.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.Extensions.Logging;

namespace CSharp;

public class Assignments(ILogger<Assignments> _logger)
{
public Data? NullableData { get; set; } = default;

public void NullConditional()
{
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; }
}
}
28 changes: 28 additions & 0 deletions csharp/CSharp/CollectionExpressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>
Span<int> spanNumbers = numbers;
_logger.LogInformation($"Implicit Conversion int[] -> span<int>: {string.Join(',', spanNumbers.ToArray())}");

// T[] -> ReadOnlySpan<T>
ReadOnlySpan<int> readOnlyNumbers = numbers;
_logger.LogInformation($"Implicit Conversion int[] -> ReadOnlySpan<int>: {string.Join(',', readOnlyNumbers.ToArray())}");
}

public void CallMethods()
{
SomeMethod("arg1", "arg2", "arg3");
Expand All @@ -50,4 +63,19 @@ public void SomeOtherMethod(string[] args)
{
_logger.LogInformation($"SomeOtherMethod is called with args: {string.Join(',', args)}");
}

public void ExtensionMembers()
{
IEnumerable<int> empty = [];
IEnumerable<int> numbers = [1, 2, 3];

_logger.LogInformation($"Extension property (instance-like): empty.IsEmpty => {empty.IsEmpty}");
_logger.LogInformation($"Extension property (instance-like): numbers.IsEmpty => {numbers.IsEmpty}");

var combined = IEnumerable<int>.Combine(numbers, [4, 5]);
_logger.LogInformation($"Type extension method (static-like): IEnumerable<int>.Combine() => {string.Join(',', combined)}");

var initialized = IEnumerable<int>.Initialized;
_logger.LogInformation($"Type extension property (static-like): IEnumerable<int>.Initialized count => {initialized.Count()}");
}
}
15 changes: 15 additions & 0 deletions csharp/CSharp/ExtensionMembers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace CSharp;

public static class ExtensionMembers
{
extension<T>(IEnumerable<T> source)
{
public bool IsEmpty => !source.Any();
}

extension<T>(IEnumerable<T>)
{
public static IEnumerable<T> Combine(IEnumerable<T> first, IEnumerable<T> second) => first.Concat(second);
public static IEnumerable<T> Initialized => [];
}
}
12 changes: 11 additions & 1 deletion csharp/CSharp/LambdaParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace CSharp;

public class LambdaParameters(ILogger<CollectionExpressions> _logger)
public class LambdaParameters(ILogger<LambdaParameters> _logger)
{
public void OptionalParameters()
{
Expand Down Expand Up @@ -32,4 +32,14 @@ void Params(params int[] values) { }
optional();
@params();
}

private delegate bool TryParse<T>(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<int> parse = (text, out result) => int.TryParse(text, out result);

_logger.LogInformation($"(text, out result) => int.TryParse: ok={parse("42", out int value)}, result={value}");
}
}
12 changes: 11 additions & 1 deletion csharp/CSharp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

var serviceCollection = new ServiceCollection();

serviceCollection.AddSingleton<Assignments>();
serviceCollection.AddSingleton<CollectionExpressions>();
serviceCollection.AddSingleton<EncodingDecoding>();
serviceCollection.AddSingleton<LambdaParameters>();
serviceCollection.AddSingleton<Params>();
serviceCollection.AddSingleton<PropertiesAndFields>();

serviceCollection.AddLogging(options =>
{
Expand All @@ -17,19 +19,27 @@

var serviceProvider = serviceCollection.BuildServiceProvider();

var assignments = serviceProvider.GetRequiredService<Assignments>();
var collectionExpressions = serviceProvider.GetRequiredService<CollectionExpressions>();
var encodingDecoding = serviceProvider.GetRequiredService<EncodingDecoding>();
var lambdaParameters = serviceProvider.GetRequiredService<LambdaParameters>();
var @params = serviceProvider.GetRequiredService<Params>();
var propertiesAndFields = serviceProvider.GetRequiredService<PropertiesAndFields>();

@params.Use();

assignments.NullConditional();

collectionExpressions.EmptyCollectionInitialization();
collectionExpressions.CollectionInitialization();
collectionExpressions.Conversions();
collectionExpressions.CallMethods();

lambdaParameters.OptionalParameters();
lambdaParameters.ParamsArrayParameters();
lambdaParameters.NewAcceptedBehavior();
lambdaParameters.ParameterModifiersWithoutTypes();

encodingDecoding.RunShowCases();

encodingDecoding.RunShowCases();
propertiesAndFields.FieldKeyword();
18 changes: 18 additions & 0 deletions csharp/CSharp/PropertiesAndFields.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Microsoft.Extensions.Logging;

namespace CSharp;

public class PropertiesAndFields(ILogger<PropertiesAndFields> _logger)
{
string _field = "field";

public string WithOutFieldKeyword { get => _field; set => _field = value; }
public string WithFieldKeyword { get; set => field = value.Trim(); } = "WithField";

public void FieldKeyword()
{
_logger.LogInformation($"_field => '{_field}'");
_logger.LogInformation($"WithOutFieldKeyword => '{WithOutFieldKeyword}'");
_logger.LogInformation($"WithFieldKeyword => '{WithFieldKeyword}'");
}
}
2 changes: 2 additions & 0 deletions csharp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ projects.

What we have learned and implemented so far are the following.

- Assignments
- Collection expressions
- Different Params type usage
- Encoding Decoding
- Lambda Parameters
- Properties and fields
5 changes: 5 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"test": {
"runner": "Microsoft.Testing.Platform"
}
}
Loading