dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.26k stars 4.73k forks source link

[API Proposal]: `StrongBox.Create` #105400

Open colejohnson66 opened 3 months ago

colejohnson66 commented 3 months ago

Background and motivation

Many generic types have static, non-generic, classes with a Create helper method. This allows the compiler to infer the generic argument. StrongBox<T> does not.

Arguably, since StrongBox<T> is in System.Runtime.CompilerServices, it should not be used by user code. However, it is a useful type in multithreaded code as it allows atomic updates (by nature of being heap allocated), and avoids boxing/unboxing overhead; only an allocation. The unboxing overhead can be eliminated with Unsafe.Unbox, but, as the name suggests, it's an unsafe API.

API Proposal

namespace System.Runtime.CompilerServices;

public static class StrongBox
{
    public static StrongBox<T> Create<T>(T value);
}

API Usage

Old code:

Interlocked.Exchange(ref _currentValue, new StrongBox<decimal>(newValue));

New code:

Interlocked.Exchange(ref _currentValue, StrongBox.Create(newValue));

Sure, target-typed new could be used on the old code, but some people disable that lint if the target type is not evident.

Alternative Designs

No response

Risks

No response

dotnet-policy-service[bot] commented 3 months ago

Tagging subscribers to this area: @dotnet/area-system-runtime-compilerservices See info in area-owners.md if you want to be subscribed.

julealgon commented 3 months ago

Why do we keep adding factory methods like this to the public API instead of just adding generic type inference to constructors?

Seems like such a low-hanging fruit at this point that would increase consistency in the language with not-so-much effort (considering there is already generic type inference in methods), and would finally remove the need for this whole "class" of dumbh factory methods that were added just to circumvent the lack of generic type inference in constructors, like KeyValuePair.Create, Tuple.Create (back then when we still used reference tuples...), etc.

Factory methods should only be needed when they add valuable semantics to the code IMHO (e.g. TimeSpan.FromSeconds). This is not one of those cases.