-
Notifications
You must be signed in to change notification settings - Fork 0
Null elements #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Null elements #13
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| [*.cs] | ||
|
|
||
| # SA1600: Elements should be documented | ||
| dotnet_diagnostic.SA1600.severity = none | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net9.0</TargetFramework> | ||
| <LangVersion>latest</LangVersion> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| <IsPackable>false</IsPackable> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <None Remove="stylecop.json" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <AdditionalFiles Include="stylecop.json" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="coverlet.collector" Version="6.0.2" /> | ||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" /> | ||
| <PackageReference Include="NUnit" Version="4.2.2" /> | ||
| <PackageReference Include="NUnit.Analyzers" Version="4.4.0" /> | ||
| <PackageReference Include="NUnit3TestAdapter" Version="4.6.0" /> | ||
| <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556"> | ||
| <PrivateAssets>all</PrivateAssets> | ||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
| </PackageReference> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\NullElements\NullElements.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <Using Include="NUnit.Framework" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| // <copyright file="NullElementsTests.cs" company="Kalinin Andrew"> | ||
| // Copyright (c) Kalinin Andrew. All rights reserved. | ||
| // </copyright> | ||
|
|
||
| namespace NullElements.Tests | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Используйте file-scoped namespaces, так сейчас не пишут уже |
||
| { | ||
| public class NullElementsTests | ||
| { | ||
| [Test] | ||
| public void Add_NumberToEmptyList_ShouldIncreaseCountByOne() | ||
| { | ||
| var testList = new MyList<int>(); | ||
| testList.Add(5); | ||
|
|
||
| Assert.That(testList.Count, Is.EqualTo(1)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Add_Overflow_ShouldDoubleInternalArraySize() | ||
| { | ||
| var testList = new MyList<int>(); | ||
| var initialCapacity = 10; | ||
| for (int i = 0; i < initialCapacity + 1; ++i) | ||
| { | ||
| testList.Add(i); | ||
| } | ||
|
|
||
| Assert.That(testList.Count, Is.EqualTo(11)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void GetEnumerator_ValidData_ShouldIterateInCorrectOrder() | ||
| { | ||
| var testList = new MyList<int>(); | ||
| testList.Add(1); | ||
| testList.Add(2); | ||
|
|
||
| var result = new System.Collections.Generic.List<int>(); | ||
| foreach (var item in testList) | ||
| { | ||
| result.Add(item); | ||
| } | ||
|
|
||
| Assert.That(result, Is.EqualTo(new[] { 1, 2 })); | ||
| } | ||
|
|
||
| [Test] | ||
| public void GetEnumerator_WhenListIsEmpty_ShouldNotIterate() | ||
| { | ||
| var testList = new MyList<string>(); | ||
|
|
||
| var iterations = 0; | ||
| foreach (var item in testList) | ||
| { | ||
| iterations++; | ||
| } | ||
|
|
||
| Assert.That(iterations, Is.EqualTo(0)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void CountNulls_String_ShouldReturnCorrectCount() | ||
| { | ||
| var testList = new MyList<string>(); | ||
| testList.Add("hello"); | ||
| testList.Add(null); | ||
|
Check warning on line 66 in NullElements/NullElements.Tests/NullElementsTests.cs
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут стоило явно заглушить предупреждения nullability, хотя бы с помощью оператора |
||
| testList.Add(string.Empty); | ||
| testList.Add("world"); | ||
|
|
||
| var result = Counter.CountNulls(testList, new StringNullChecker()); | ||
|
|
||
| Assert.That(result, Is.EqualTo(2)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void CountNulls_Int_ShouldReturnCorrectCountZeros() | ||
| { | ||
| var testList = new MyList<int>(); | ||
| testList.Add(0); | ||
| testList.Add(1); | ||
| testList.Add(0); | ||
|
|
||
| var result = Counter.CountNulls(testList, new IntNullChecker()); | ||
|
|
||
| Assert.That(result, Is.EqualTo(2)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void CountNulls_WhenIntListIsEmpty_ShouldReturnZero() | ||
| { | ||
| var testList = new MyList<int>(); | ||
|
|
||
| var result = Counter.CountNulls(testList, new IntNullChecker()); | ||
|
|
||
| Assert.That(result, Is.EqualTo(0)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void CountNulls_WhenStringListIsEmpty_ShouldReturnZero() | ||
| { | ||
| var testList = new MyList<string>(); | ||
|
|
||
| var result = Counter.CountNulls(testList, new StringNullChecker()); | ||
|
|
||
| Assert.That(result, Is.EqualTo(0)); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| { | ||
| // ACTION REQUIRED: This file was automatically added to your project, but it | ||
| // will not take effect until additional steps are taken to enable it. See the | ||
| // following page for additional information: | ||
|
Comment on lines
+2
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут говорится, что надо конфигурацию применить и удалить этот комментарий |
||
| // | ||
| // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md | ||
|
|
||
| "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", | ||
| "settings": { | ||
| "documentationRules": { | ||
| "companyName": "Kalinin Andrew", | ||
| "copyrightText": "Copyright (c) {companyName}. All rights reserved." | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| | ||
| Microsoft Visual Studio Solution File, Format Version 12.00 | ||
| # Visual Studio Version 17 | ||
| VisualStudioVersion = 17.13.35806.99 d17.13 | ||
| MinimumVisualStudioVersion = 10.0.40219.1 | ||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NullElements", "NullElements\NullElements.csproj", "{2BA0FF1E-3004-4D5F-A36F-9E7122EE2145}" | ||
| EndProject | ||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NullElements.Tests", "NullElements.Tests\NullElements.Tests.csproj", "{1AE28732-923A-4DDE-BE64-28751F09CC28}" | ||
| EndProject | ||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36D591C7-65C7-A0D1-1CBC-10CDE441BDC8}" | ||
| ProjectSection(SolutionItems) = preProject | ||
| .editorconfig = .editorconfig | ||
| EndProjectSection | ||
| EndProject | ||
| Global | ||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
| Debug|Any CPU = Debug|Any CPU | ||
| Release|Any CPU = Release|Any CPU | ||
| EndGlobalSection | ||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
| {2BA0FF1E-3004-4D5F-A36F-9E7122EE2145}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {2BA0FF1E-3004-4D5F-A36F-9E7122EE2145}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {2BA0FF1E-3004-4D5F-A36F-9E7122EE2145}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {2BA0FF1E-3004-4D5F-A36F-9E7122EE2145}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| {1AE28732-923A-4DDE-BE64-28751F09CC28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {1AE28732-923A-4DDE-BE64-28751F09CC28}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {1AE28732-923A-4DDE-BE64-28751F09CC28}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {1AE28732-923A-4DDE-BE64-28751F09CC28}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| EndGlobalSection | ||
| GlobalSection(SolutionProperties) = preSolution | ||
| HideSolutionNode = FALSE | ||
| EndGlobalSection | ||
| GlobalSection(ExtensibilityGlobals) = postSolution | ||
| SolutionGuid = {979D0980-DB24-4BC7-909D-644F6A87E14F} | ||
| EndGlobalSection | ||
| EndGlobal |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| // <copyright file="Counter.cs" company="Kalinin Andrew"> | ||
| // Copyright (c) Kalinin Andrew. All rights reserved. | ||
| // </copyright> | ||
|
|
||
| namespace NullElements | ||
| { | ||
| /// <summary> | ||
| /// Provides utility methods for working with collections. | ||
| /// </summary> | ||
| public static class Counter | ||
| { | ||
| /// <summary> | ||
| /// Counts elements that match null-equivalent conditions. | ||
| /// </summary> | ||
| /// <typeparam name="T">The type of elements in the list.</typeparam> | ||
| /// <param name="list">The collection to inspect.</param> | ||
| /// <param name="checker">The null-equivalence checker implementation.</param> | ||
| /// <returns>The number of null-equivalent elements.</returns> | ||
| /// <exception cref="ArgumentNullException">Thrown when list or checker is null.</ | ||
| public static int CountNulls<T>(MyList<T> list, ICheckNulls<T> checker) | ||
| { | ||
| if (list == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(list)); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ArgumentNullException.ThrowIfNull |
||
| } | ||
|
|
||
| if (checker == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(checker)); | ||
| } | ||
|
|
||
| int count = 0; | ||
|
|
||
| foreach (var item in list) | ||
| { | ||
| if (checker.IsNull(item)) | ||
| { | ||
| count++; | ||
| } | ||
| } | ||
|
|
||
| return count; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // <copyright file="ICheckNulls.cs" company="Kalinin Andrew"> | ||
| // Copyright (c) Kalinin Andrew. All rights reserved. | ||
| // </copyright> | ||
|
|
||
| namespace NullElements | ||
| { | ||
| /// <summary> | ||
| /// Interface for checking if elements meet null-equivalent conditions. | ||
| /// </summary> | ||
| /// <typeparam name="T">The type of elements to check.</typeparam> | ||
| public interface ICheckNulls<T> | ||
| { | ||
| /// <summary> | ||
| /// Determines if an item should be considered null-equivalent. | ||
| /// </summary> | ||
| /// <param name="item">The item to check.</param> | ||
| /// <returns>True if the item is considered null-equivalent, otherwise False.</returns> | ||
| bool IsNull(T item); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| // <copyright file="IntNullChecker.cs" company="Kalinin Andrew"> | ||
| // Copyright (c) Kalinin Andrew. All rights reserved. | ||
| // </copyright> | ||
|
|
||
| namespace NullElements | ||
| { | ||
| /// <summary> | ||
| /// Null-equivalence checker for integer values. | ||
| /// </summary> | ||
| public class IntNullChecker : ICheckNulls<int> | ||
| { | ||
| /// <summary> | ||
| /// Determines if an integer is zero. | ||
| /// </summary> | ||
| /// <param name="item">The integer to check.</param> | ||
| /// <returns>True if the value is zero, otherwise False.</returns> | ||
| public bool IsNull(int item) => item == 0; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| // <copyright file="MyList.cs" company="Kalinin Andrew"> | ||
| // Copyright (c) Kalinin Andrew. All rights reserved. | ||
| // </copyright> | ||
|
|
||
| using System.Collections; | ||
|
|
||
| /// <summary> | ||
| /// Custom generic list implementation with dynamic resizing. | ||
| /// </summary> | ||
| /// <typeparam name="T">The type of elements in the list.</typeparam> | ||
| public class MyList<T> : IEnumerable<T> | ||
| { | ||
| private T[] items; | ||
|
|
||
| private int count; | ||
|
|
||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="MyList{T}"/> class. | ||
| /// </summary> | ||
| public MyList() | ||
| { | ||
| this.items = new T[4]; | ||
| this.count = 0; | ||
| } | ||
|
|
||
| public int Count => this.count; | ||
|
|
||
| /// <summary> | ||
| /// Adds an item to the end of the list. | ||
| /// </summary> | ||
| /// <param name="item">The item to add.</param> | ||
| public void Add(T item) | ||
| { | ||
| if (this.count == this.items.Length) | ||
| { | ||
| Array.Resize(ref this.items, this.items.Length == 0 ? 10 : this.items.Length * 2); | ||
| } | ||
|
|
||
| this.items[this.count] = item; | ||
| this.count++; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Returns an enumerator that iterates through the collection. | ||
| /// </summary> | ||
| /// <returns>An enumerator for the list.</returns> | ||
| public IEnumerator<T> GetEnumerator() | ||
| { | ||
| for (int i = 0; i < this.count; ++i) | ||
| { | ||
| yield return this.items[i]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Так оно не будет проверять на то, что список не поменялся. Можно было просто запомнить count в локальной переменной и на каждой итерации сравнивать её с текущим count |
||
| } | ||
| } | ||
|
|
||
| IEnumerator IEnumerable.GetEnumerator() | ||
| { | ||
| return this.GetEnumerator(); | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Использовали бы |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFramework>net9.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <None Remove="stylecop.json" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <AdditionalFiles Include="stylecop.json" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556"> | ||
| <PrivateAssets>all</PrivateAssets> | ||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
| </PackageReference> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| // <copyright file="Program.cs" company="Kalinin Andrew"> | ||
| // Copyright (c) Kalinin Andrew. All rights reserved. | ||
| // </copyright> | ||
|
|
||
| using NullElements; | ||
|
|
||
| var intList = new MyList<int>(); | ||
| intList.Add(0); | ||
| intList.Add(0); | ||
| intList.Add(0); | ||
| intList.Add(0); | ||
|
|
||
| Console.WriteLine(Counter.CountNulls(intList, new IntNullChecker())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Это стоило выключать только для тестов, для всего проекта не надо