Closed RamType0 closed 9 months ago
However, if there is a value with exposing a property or method for GetInvocationList().Length that would be fine
@terrajobst What would be a good API name for that?
As @weltkante pointed out, special casing the single-cast delegate fast path is fairly common. It would be nice to introduce proper API to replace the solutions based on private reflection:
@jkotas
@terrajobst What would be a good API name for that?
The objection to exposing the proposed properties was raised by @GrabYourPitchforks, so I let him speak to the details here.
My understanding was that InvocationCount
would return the number of elements the iterator would produce (equivalent to GetInvocationList().Length
) and that the Boolean IsSingleInvocation
would be equivalent to InvocationCount == 0
, so those names seemed reasonable.
In order for me to propose better names is dependent upon understanding the desired semantics.
My understanding was that InvocationCount would return the number of elements the iterator would produce
Yes, that's correct.
Exposing InvocationCount with assumption that it is a fast O(1) operation locks us into the current internal delegate implementation. This assumption would be broken if we were to change the internal delegate implementation to a different data structure that does not allow fast O(1) length operation. (The internal data structure used by delegates was changed at least once in .NET runtime history.) This lock-in is not a showstopper, I am just pointing out the downside of exposing full InvocationCount when the API use cases only need to check for == 1.
Marking the API as I forgot to do that in the meeting 🤦
I was concerned that Delegate.InvocationCount
might be misconstrued to mean the number of times the Delegate
has been invoked.
I was concerned that Delegate.InvocationCount might be misconstrued
Renamed to GetInvocationListLength()
for clarity.
I have updated the proposal at the top with the feedback so far. Any comments?
I have updated the proposal at the top with the feedback so far. Any comments?
IsSingle
is probably meant to be a boolean?
I think this is ready for next round of API review discussion.
IsSingle
got changed to the first alternative proposal of HasSingleTarget
GetInvocationListLength
was removed, pending a more concrete need in the future.public class Delegate
{
// Existing API
// public virtual System.Delegate[] GetInvocationList();
// Returns whether the delegate has a single target. It is a property to highlight that it is guaranteed
// to be a very cheap operation that is important for set of scenarios addressed by this proposal.
public bool HasSingleTarget { get; }
// Returns invocation list enumerator
public static InvocationListEnumerator<TDelegate> EnumerateInvocationList<TDelegate>(TDelegate d) where TDelegate : Delegate;
// The shape of this enumerator matches existing StringBuilder.ChunkEnumerator and Activity.Enumerator
// Neither of these existing enumerators implement IEnumerable and IEnumerator. This can be changed.
// Q: How are we deciding whether enumerators like this should implement IEnumerable and IEnumerator?
// Note that implementing these interfaces makes each instantiation of the type more expensive, so it is a tradeoff.
public struct InvocationListEnumerator<TDelegate> where TDelegate : Delegate
{
public TDelegate Current { get; }
public bool MoveNext();
// EditorBrowsable to match existing StringBuilder.ChunkEnumerator and Activity.Enumerator
[EditorBrowsable(EditorBrowsableState.Never)] // Only here to make foreach work
public InvocationListEnumerator<TDelegate> GetEnumerator() => this;
}
}
I've wanted to try out the new APIs but they don't seem to appear in the daily builds, am I missing something? Sorry if there's known delays between PRs and daily builds, didn't see anything being mentioned.
Yes, .NET SDK runs behind dotnet/runtime. You can check https://github.com/dotnet/installer/blob/main/eng/Version.Details.xml#L30 to see the dotnet/runtime commit that is in the SDK.
Also https://github.com/dotnet/runtime/blob/main/docs/project/dogfooding.md#advanced-scenario---using-a-daily-build-of-microsoftnetcoreapp has instructions for how to get daily builds of dotnet/runtime without waiting for the bits to flow to .NET SDK.
Background and Motivation
Currently,we have an API to invocation list of MulticastDelegate,it is MulticastDelegate.GetInvocationList().
It allocates array every time we call it. And maybe that's why we have internal HasSingleTarget property in it.
We need handsome,and performant API.
Proposed API
Original rejected proposal