diff --git a/docs/csharp/language-reference/builtin-types/snippets/unions/MemberProvider.cs b/docs/csharp/language-reference/builtin-types/snippets/unions/MemberProvider.cs index 7daa52d08cb6d..c5b01ab8ef560 100644 --- a/docs/csharp/language-reference/builtin-types/snippets/unions/MemberProvider.cs +++ b/docs/csharp/language-reference/builtin-types/snippets/unions/MemberProvider.cs @@ -1,6 +1,6 @@ // [System.Runtime.CompilerServices.Union] -public record class Outcome : Outcome.IUnionMembers +public struct Outcome : Outcome.IUnionMembers { private readonly object? _value; @@ -11,9 +11,35 @@ public interface IUnionMembers static Outcome Create(T? value) => new(value); static Outcome Create(Exception? value) => new(value); object? Value { get; } + + // only when needed + bool TryGetValue(out T value); + bool TryGetValue(out Exception value); } object? IUnionMembers.Value => _value; + + public bool TryGetValue(out T value) + { + if (_value is T t) + { + value = t; + return true; + } + value = default!; + return false; + } + + public bool TryGetValue(out Exception value) + { + if (_value is Exception e) + { + value = e; + return true; + } + value = default!; + return false; + } } // diff --git a/docs/csharp/language-reference/builtin-types/union.md b/docs/csharp/language-reference/builtin-types/union.md index 760b376c8e80e..303176b117410 100644 --- a/docs/csharp/language-reference/builtin-types/union.md +++ b/docs/csharp/language-reference/builtin-types/union.md @@ -171,7 +171,7 @@ The compiler prefers `TryGetValue` over the `Value` property when implementing p ### Union member providers -A union type can delegate its union members to a nested `IUnionMembers` interface. When this interface is present, the compiler looks for `Create` factory methods instead of constructors: +A union type can delegate its union members to a nested `IUnionMembers` interface. When this interface is present, the `union` type behaves as a *union member provider*. The compiler generates code to call the `IUnionMembers` interface. It won't generate calls to members declared on the union type that aren't members of the nested `IUnionMembers` interface. As the following example shows, that means you must add the necessary factory methods and the appropriate `TryGetValue` methods for all case types: :::code language="csharp" source="snippets/unions/MemberProvider.cs" id="MemberProvider":::