diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 5467cf247a4d0e..2c48c4cba7ffd1 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -897,6 +897,7 @@ + @@ -938,6 +939,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs new file mode 100644 index 00000000000000..71a88be48a6a33 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/IUnion.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.CompilerServices +{ + /// + /// Provides a common interface for accessing the contents of a union type at runtime. + /// + /// + /// + /// The C# compiler automatically implements this interface on types generated by union declarations. + /// User-defined types annotated with may also implement this interface + /// to provide runtime access to the union's value. Implementing this interface is not required + /// for union behaviors provided by the compiler. + /// + /// + /// + public interface IUnion + { + /// + /// Gets the value contained in the union, or if the union has no value. + /// + /// + /// The current value of the union as one of its case types, or . + /// + object? Value { get; } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs new file mode 100644 index 00000000000000..e1e6ea64ebfeee --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/UnionAttribute.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.CompilerServices +{ + /// + /// Indicates that a class or struct is a union type, enabling compiler support for union behaviors. + /// + /// + /// + /// Any class or struct annotated with this attribute is recognized by the C# compiler as a union type. + /// Union types may support behaviors such as implicit conversions from case types, pattern matching + /// that unwraps the union's contents, and switch exhaustiveness checking. + /// + /// + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] + public sealed class UnionAttribute : Attribute + { + } +} diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index abfa9d8f41fb46..1e205d855b5d0a 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -14063,6 +14063,10 @@ public partial interface ITuple object? this[int index] { get; } int Length { get; } } + public partial interface IUnion + { + object? Value { get; } + } public enum LoadHint { Default = 0, @@ -14489,6 +14493,11 @@ public sealed partial class UnsafeValueTypeAttribute : System.Attribute { public UnsafeValueTypeAttribute() { } } + [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple=false, Inherited=false)] + public sealed partial class UnionAttribute : System.Attribute + { + public UnionAttribute() { } + } public readonly partial struct ValueTaskAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion, System.Runtime.CompilerServices.INotifyCompletion { private readonly object _dummy; diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs index 431c72b61c7ce6..a55efd31bae16f 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/AttributesTests.cs @@ -426,5 +426,18 @@ public static void OverloadResolutionPriorityAttributeTests() var attr = new OverloadResolutionPriorityAttribute(42); Assert.Equal(42, attr.Priority); } + + [Fact] + public static void UnionAttributeTests() + { + var attr = new UnionAttribute(); + Assert.NotNull(attr); + + var usage = (AttributeUsageAttribute)Attribute.GetCustomAttribute(typeof(UnionAttribute), typeof(AttributeUsageAttribute))!; + Assert.Equal(AttributeTargets.Class | AttributeTargets.Struct, usage.ValidOn); + Assert.False(usage.AllowMultiple); + Assert.False(usage.Inherited); + } + } }