Skip to content

Commit

Permalink
Merge pull request #253 from kasperk81/patch-1
Browse files Browse the repository at this point in the history
Add ext. methods to replace LINQ in generated code
  • Loading branch information
andrueastman authored Jun 13, 2024
2 parents 50492a5 + a4907ac commit 2bbc677
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.9.6] - 2024-06-12

- Add `IEnumerable<T>` extension methods to remove LINQ dependency from generated code.

### Added

## [1.9.5] - 2024-06-03

### Added
Expand Down
85 changes: 85 additions & 0 deletions Microsoft.Kiota.Abstractions.Tests/IEnumerableExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using Microsoft.Kiota.Abstractions.Extensions;
using Xunit;

public class IEnumerableExtensionsTests
{
[Fact]
public void AsList_WithNullInput_ReturnsNull()
{
IEnumerable<int> nullEnumerable = null;
var result = nullEnumerable.AsList();
Assert.Null(result);
}

[Fact]
public void AsList_WithListInput_ReturnsSameList()
{
var originalList = new List<int> { 1, 2, 3 };
var resultList = originalList.AsList();
Assert.Same(originalList, resultList);
}

[Fact]
public void AsList_WithEnumerableInput_ReturnsNewList()
{
IEnumerable<int> enumerable = new int[] { 1, 2, 3 };
var resultList = enumerable.AsList();
Assert.NotSame(enumerable, resultList);
Assert.Equal(enumerable, resultList);
}

[Fact]
public void AsArray_WithNullInput_ReturnsNull()
{
IEnumerable<int> nullEnumerable = null;
var result = nullEnumerable.AsArray();
Assert.Null(result);
}

[Fact]
public void AsArray_WithArrayInput_ReturnsSameArray()
{
var originalArray = new int[] { 1, 2, 3 };
var resultArray = originalArray.AsArray();
Assert.Same(originalArray, resultArray);
}

[Fact]
public void AsArray_WithListInput_ReturnsNewArray()
{
var list = new List<int> { 1, 2, 3 };
var resultArray = list.AsArray();
Assert.NotSame(list, resultArray);
Assert.Equal(list, resultArray);
}

[Fact]
public void AsArray_WithEnumerableInput_ReturnsNewArray()
{
IEnumerable<int> enumerable = new int[] { 1, 2, 3 };
var resultArray = enumerable.AsArray();
// We expect a new array only if the input is not already an array
if (enumerable is not int[])
{
Assert.NotSame(enumerable, resultArray);
}
Assert.Equal(enumerable, resultArray);
}

[Fact]
public void AsArray_WithNonCollectionEnumerableInput_ReturnsNewArray()
{
IEnumerable<int> enumerable = GetEnumerable();
var resultArray = enumerable.AsArray();
Assert.Equal(new int[] { 1, 2, 3 }, resultArray);
}

private IEnumerable<int> GetEnumerable()
{
yield return 1;
yield return 2;
yield return 3;
}
}
2 changes: 1 addition & 1 deletion src/Microsoft.Kiota.Abstractions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<PackageProjectUrl>https://aka.ms/kiota/docs</PackageProjectUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<Deterministic>true</Deterministic>
<VersionPrefix>1.9.5</VersionPrefix>
<VersionPrefix>1.9.6</VersionPrefix>
<VersionSuffix></VersionSuffix>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<SignAssembly>false</SignAssembly>
Expand Down
75 changes: 75 additions & 0 deletions src/extensions/IEnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
// See License in the project root for license information.
// ------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;

namespace Microsoft.Kiota.Abstractions.Extensions
{
/// <summary>
/// Extension methods for <see cref="IEnumerable{T}"/>
/// </summary>
public static class IEnumerableExtensions
{
/// <summary>
/// Converts an <see cref="IEnumerable{T}"/> to a <see cref="List{T}"/>.
/// </summary>
/// <typeparam name="T">The type of elements in the collection.</typeparam>
/// <param name="e">The enumerable to convert.</param>
/// <returns>A <see cref="List{T}"/> containing the elements of the enumerable, or <c>null</c> if the input is <c>null</c>.</returns>
public static List<T>? AsList<T>(this IEnumerable<T>? e)
{
if (e is null) return null;

if (e is List<T> list) return list;

return new List<T>(e);
}

/// <summary>
/// Converts an <see cref="IEnumerable{T}"/> to an array.
/// </summary>
/// <typeparam name="T">The type of elements in the collection.</typeparam>
/// <param name="e">The enumerable to convert.</param>
/// <returns>An array containing the elements of the enumerable, or <c>null</c> if the input is <c>null</c>.</returns>
public static T[]? AsArray<T>(this IEnumerable<T>? e)
{
if (e is null) return null;

if (e is T[] array) return array;

T[]? result = null;

if (e is ICollection<T> collection)
{
// Allocate an array with the exact size
result = AllocateOnHeap(collection.Count);
collection.CopyTo(result, 0);
return result;
}

// First pass to count the elements
int count = 0;
foreach (var item in e) count++;

result = AllocateOnHeap(count);

// Second pass to copy the elements
count = 0;
foreach (var item in e) result[count++] = item;
return result;

static T[] AllocateOnHeap(int count)
{
#if NET5_0_OR_GREATER
return GC.AllocateUninitializedArray<T>(count);
#else
return new T[count];
#endif
}
}
}
}

0 comments on commit 2bbc677

Please sign in to comment.