Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonCropp committed Dec 27, 2024
2 parents c5b91a2 + 7612342 commit 49564db
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 7 deletions.
2 changes: 1 addition & 1 deletion apiCount.include.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
**API count: 434**
**API count: 435**
5 changes: 5 additions & 0 deletions api_list.include.md
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,11 @@
* `bool TryParse(string?, IFormatProvider?, byte)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryparse#system-byte-tryparse(system-string-system-iformatprovider-system-byte@))


#### DelegatePolyfill

* `InvocationListEnumerator<TDelegate> EnumerateInvocationList<TDelegate>(TDelegate?) where TDelegate : Delegate` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.delegate.enumerateinvocationlist)


#### GuidPolyfill

* `Guid CreateVersion7()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.createversion7#system-guid-createversion7)
Expand Down
7 changes: 6 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The package targets `netstandard2.0` and is designed to support the following ru
* `net5.0`, `net6.0`, `net7.0`, `net8.0`, `net9.0`


**API count: 434**<!-- singleLineInclude: apiCount. path: /apiCount.include.md -->
**API count: 435**<!-- singleLineInclude: apiCount. path: /apiCount.include.md -->


**See [Milestones](../../milestones?state=closed) for release notes.**
Expand Down Expand Up @@ -959,6 +959,11 @@ The class `Polyfill` includes the following extension methods:
* `bool TryParse(string?, IFormatProvider?, byte)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryparse#system-byte-tryparse(system-string-system-iformatprovider-system-byte@))


#### DelegatePolyfill

* `InvocationListEnumerator<TDelegate> EnumerateInvocationList<TDelegate>(TDelegate?) where TDelegate : Delegate` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.delegate.enumerateinvocationlist)


#### GuidPolyfill

* `Guid CreateVersion7()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.createversion7#system-guid-createversion7)
Expand Down
1 change: 1 addition & 0 deletions src/ApiBuilderTests/BuildApiTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public void RunWithRoslyn()
WriteHelper(types, "RegexPolyfill", writer, ref count);
WriteHelper(types, "StringPolyfill", writer, ref count);
WriteHelper(types, "BytePolyfill", writer, ref count);
WriteHelper(types, "DelegatePolyfill", writer, ref count);
WriteHelper(types, "GuidPolyfill", writer, ref count);
WriteHelper(types, "DateTimePolyfill", writer, ref count);
WriteHelper(types, "DateTimeOffsetPolyfill", writer, ref count);
Expand Down
65 changes: 65 additions & 0 deletions src/Polyfill/DelegatePolyfill.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// <auto-generated />


#pragma warning disable

namespace Polyfills;

using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;

[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
#if PolyPublic
public
#endif
static partial class DelegatePolyfill
{
/// <summary>
/// Gets an enumerator for the invocation targets of this delegate.
/// </summary>
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.delegate.enumerateinvocationlist
#if NET9_0_OR_GREATER
public static Delegate.InvocationListEnumerator<TDelegate> EnumerateInvocationList<TDelegate>(TDelegate? target) where TDelegate : Delegate =>
Delegate.EnumerateInvocationList(target);
#else
public static InvocationListEnumerator<TDelegate> EnumerateInvocationList<TDelegate>(TDelegate? target) where TDelegate : Delegate =>
new InvocationListEnumerator<TDelegate>(target);

/// <summary>
/// Provides an enumerator for the invocation list of a delegate.
/// </summary>
/// <typeparam name="TDelegate">Delegate type being enumerated.</typeparam>
public struct InvocationListEnumerator<TDelegate>
where TDelegate : Delegate
{
Delegate[] delegates;
int index = -1;

internal InvocationListEnumerator(Delegate target) =>
delegates = target.GetInvocationList();

public TDelegate Current { get; private set; }

public bool MoveNext()
{
int index = this.index + 1;
if (index == delegates.Length)
{
return false;
}

Current = (TDelegate) delegates[index];
this.index = index;
return true;
}

[EditorBrowsable(EditorBrowsableState.Never)]
public InvocationListEnumerator<TDelegate> GetEnumerator() => this;
}
#endif

}
27 changes: 22 additions & 5 deletions src/Tests/PolyfillTests_Delegate.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
partial class PolyfillTests
{
public static event EventHandler? MyEvent;
public static event EventHandler? EventForHasSingleTarget;

[Test]
public void HasSingleTarget()
{
MyEvent += Handler;
Assert.IsTrue(MyEvent.HasSingleTarget());
MyEvent += Handler;
Assert.IsFalse(MyEvent.HasSingleTarget());
EventForHasSingleTarget += Handler;
Assert.IsTrue(EventForHasSingleTarget.HasSingleTarget());
EventForHasSingleTarget += Handler;
Assert.IsFalse(EventForHasSingleTarget.HasSingleTarget());
var action = () =>
{
};
Expand All @@ -20,4 +20,21 @@ public void HasSingleTarget()
static void Handler(object? sender, EventArgs e)
{
}

public static event EventHandler? EventForEnumerateInvocationList;

[Test]
public void EnumerateInvocationList()
{
var count = 0;

EventForEnumerateInvocationList += (_, _) => count++;

foreach (var item in DelegatePolyfill.EnumerateInvocationList(EventForEnumerateInvocationList))
{
item(this, EventArgs.Empty);
}

Assert.AreEqual(1, count);
}
}

0 comments on commit 49564db

Please sign in to comment.