Struct OneOf<T1, T2, T3>
- Namespace
- REslava.Result.AdvancedPatterns
- Assembly
- REslava.Result.dll
Represents a value that can be one of three possible types. A type-safe discriminated union for functional programming patterns.
public readonly struct OneOf<T1, T2, T3> : IEquatable<OneOf<T1, T2, T3>>
Type Parameters
T1The first possible type.
T2The second possible type.
T3The third possible type.
- Implements
-
IEquatable<OneOf<T1, T2, T3>>
- Inherited Members
- Extension Methods
Remarks
OneOf<T1, T2, T3> provides a type-safe way to represent a value that can be one of three types. This is useful for scenarios where you need to handle different types of values or states without using null references, exceptions, or complex enums.
Common use cases include: - API responses with three states: Success, ClientError, ServerError - Configuration values: String, Integer, Boolean - Database operations: Created, Updated, Deleted - File operations: Read, Write, Delete results
// API response handling
OneOf<SuccessData, ClientError, ServerError> response = await CallApi();
return response.Match(
case1: data => ProcessData(data),
case2: clientError => HandleClientError(clientError),
case3: serverError => HandleServerError(serverError)
);
// Configuration parsing
OneOf<string, int, bool> config = ParseConfigValue("timeout");
var processed = config.Match(
case1: text => $"String: {text.ToUpper()}",
case2: number => $"Number: {number * 2}",
case3: flag => $"Boolean: {flag}"
);
Properties
AsT1
Gets the value as T1 if it contains T1, otherwise throws InvalidOperationException.
public T1 AsT1 { get; }
Property Value
- T1
Exceptions
- InvalidOperationException
Thrown when the OneOf contains T2 or T3.
AsT2
Gets the value as T2 if it contains T2, otherwise throws InvalidOperationException.
public T2 AsT2 { get; }
Property Value
- T2
Exceptions
- InvalidOperationException
Thrown when the OneOf contains T1 or T3.
AsT3
Gets the value as T3 if it contains T3, otherwise throws InvalidOperationException.
public T3 AsT3 { get; }
Property Value
- T3
Exceptions
- InvalidOperationException
Thrown when the OneOf contains T1 or T2.
IsT1
Gets whether the OneOf contains a value of type T1.
public bool IsT1 { get; }
Property Value
IsT2
Gets whether the OneOf contains a value of type T2.
public bool IsT2 { get; }
Property Value
IsT3
Gets whether the OneOf contains a value of type T3.
public bool IsT3 { get; }
Property Value
Methods
BindT2<TNewT2>(Func<T2, OneOf<T1, TNewT2, T3>>)
Binds the T2 value if present, otherwise propagates other types.
public OneOf<T1, TNewT2, T3> BindT2<TNewT2>(Func<T2, OneOf<T1, TNewT2, T3>> binder)
Parameters
Returns
- OneOf<T1, TNewT2, T3>
The result of the binder function or the original T1/T3.
Type Parameters
TNewT2The new T2 type.
Examples
OneOf<Error, Success, Warning> result = GetInitialResult();
OneOf<Error, ProcessedData, Warning> final = result.BindT2(success => ProcessSuccess(success));
Remarks
BindT2 (also known as flatMap or chain) allows you to chain operations that return OneOf. This is useful for sequential operations where each step might return a different type.
Exceptions
- ArgumentNullException
Thrown when binder is null.
BindT3<TNewT3>(Func<T3, OneOf<T1, T2, TNewT3>>)
Binds the T3 value if present, otherwise propagates other types.
public OneOf<T1, T2, TNewT3> BindT3<TNewT3>(Func<T3, OneOf<T1, T2, TNewT3>> binder)
Parameters
Returns
- OneOf<T1, T2, TNewT3>
The result of the binder function or the original T1/T2.
Type Parameters
TNewT3The new T3 type.
Examples
OneOf<Error, Success, Warning> result = GetInitialResult();
OneOf<Error, Success, ProcessedWarning> final = result.BindT3(warning => HandleWarning(warning));
Remarks
BindT3 (also known as flatMap or chain) allows you to chain operations that return OneOf. This is useful for sequential operations where each step might return a different type.
Exceptions
- ArgumentNullException
Thrown when binder is null.
Equals(OneOf<T1, T2, T3>)
Determines equality between two OneOf instances.
public bool Equals(OneOf<T1, T2, T3> other)
Parameters
otherOneOf<T1, T2, T3>The other OneOf to compare with.
Returns
- bool
true if the OneOf instances are equal; otherwise, false.
Equals(object?)
Determines equality between the OneOf and another object.
public override bool Equals(object? obj)
Parameters
objobjectThe object to compare with.
Returns
- bool
true if the objects are equal; otherwise, false.
FromT1(T1)
Creates a OneOf containing a T1 value.
public static OneOf<T1, T2, T3> FromT1(T1 value)
Parameters
valueT1The T1 value to wrap.
Returns
- OneOf<T1, T2, T3>
A OneOf containing the specified T1 value.
Examples
OneOf<Error, Success, Warning> result = OneOf<Error, Success, Warning>.FromT1(new NotFoundError());
FromT2(T2)
Creates a OneOf containing a T2 value.
public static OneOf<T1, T2, T3> FromT2(T2 value)
Parameters
valueT2The T2 value to wrap.
Returns
- OneOf<T1, T2, T3>
A OneOf containing the specified T2 value.
Examples
OneOf<Error, Success, Warning> result = OneOf<Error, Success, Warning>.FromT2(new Success("Data processed"));
FromT3(T3)
Creates a OneOf containing a T3 value.
public static OneOf<T1, T2, T3> FromT3(T3 value)
Parameters
valueT3The T3 value to wrap.
Returns
- OneOf<T1, T2, T3>
A OneOf containing the specified T3 value.
Examples
OneOf<Error, Success, Warning> result = OneOf<Error, Success, Warning>.FromT3(new Warning("Deprecated API"));
GetHashCode()
Returns the hash code for the OneOf.
public override int GetHashCode()
Returns
- int
The hash code.
MapT2<TNewT2>(Func<T2, TNewT2>)
Maps the T2 value if present, otherwise propagates other types.
public OneOf<T1, TNewT2, T3> MapT2<TNewT2>(Func<T2, TNewT2> mapper)
Parameters
mapperFunc<T2, TNewT2>The function to apply to the T2 value.
Returns
- OneOf<T1, TNewT2, T3>
A new OneOf with the mapped T2 value or the original T1/T3.
Type Parameters
TNewT2The new T2 type.
Examples
OneOf<Error, Success, Warning> result = ProcessData();
OneOf<Error, ProcessedSuccess, Warning> processed = result.MapT2(s => s.WithTimestamp());
Remarks
MapT2 allows you to transform the T2 value without unwrapping the OneOf. If the OneOf contains T1 or T3, the mapper function is not called and those values are propagated.
Exceptions
- ArgumentNullException
Thrown when mapper is null.
MapT3<TNewT3>(Func<T3, TNewT3>)
Maps the T3 value if present, otherwise propagates other types.
public OneOf<T1, T2, TNewT3> MapT3<TNewT3>(Func<T3, TNewT3> mapper)
Parameters
mapperFunc<T3, TNewT3>The function to apply to the T3 value.
Returns
- OneOf<T1, T2, TNewT3>
A new OneOf with the mapped T3 value or the original T1/T2.
Type Parameters
TNewT3The new T3 type.
Examples
OneOf<Error, Success, Warning> result = ProcessData();
OneOf<Error, Success, ProcessedWarning> processed = result.MapT3(w => w.WithSeverity("High"));
Remarks
MapT3 allows you to transform the T3 value without unwrapping the OneOf. If the OneOf contains T1 or T2, the mapper function is not called and those values are propagated.
Exceptions
- ArgumentNullException
Thrown when mapper is null.
Match<TResult>(Func<T1, TResult>, Func<T2, TResult>, Func<T3, TResult>)
Pattern matching - executes the appropriate function based on the contained type.
public TResult Match<TResult>(Func<T1, TResult> case1, Func<T2, TResult> case2, Func<T3, TResult> case3)
Parameters
case1Func<T1, TResult>The function to execute when the OneOf contains T1.
case2Func<T2, TResult>The function to execute when the OneOf contains T2.
case3Func<T3, TResult>The function to execute when the OneOf contains T3.
Returns
- TResult
The result of the executed function.
Type Parameters
TResultThe type of the result.
Examples
OneOf<Error, Success, Warning> result = ProcessData();
string message = result.Match(
case1: error => $"Error: {error.Message}",
case2: success => $"Success: {success.Message}",
case3: warning => $"Warning: {warning.Message}"
);
Remarks
Match provides a type-safe way to handle all three possible cases without casting. This is similar to pattern matching in functional languages.
Exceptions
- ArgumentNullException
Thrown when any case function is null.
Switch(Action<T1>, Action<T2>, Action<T3>)
Executes an action based on the contained type.
public void Switch(Action<T1> case1, Action<T2> case2, Action<T3> case3)
Parameters
case1Action<T1>The action to execute when the OneOf contains T1.
case2Action<T2>The action to execute when the OneOf contains T2.
case3Action<T3>The action to execute when the OneOf contains T3.
Examples
OneOf<Error, Success, Warning> result = ProcessData();
result.Switch(
case1: error => Console.WriteLine($"Error: {error.Message}"),
case2: success => Console.WriteLine($"Success: {success.Message}"),
case3: warning => Console.WriteLine($"Warning: {warning.Message}")
);
Remarks
Switch is useful for side effects when you don't need to return a value.
Exceptions
- ArgumentNullException
Thrown when any case action is null.
ToString()
Converts to string for debugging.
public override string ToString()
Returns
- string
A string representation of the OneOf.
Examples
OneOf<Error, Success, Warning> result = new Success("Data processed");
Console.WriteLine(result.ToString()); // "OneOf<T1, T2, T3>(T2: Success { Message = Data processed })"
Remarks
Returns the string representation of the contained value with type information. This is primarily useful for debugging and logging.
Operators
operator ==(OneOf<T1, T2, T3>, OneOf<T1, T2, T3>)
Equality operator for OneOf instances.
public static bool operator ==(OneOf<T1, T2, T3> left, OneOf<T1, T2, T3> right)
Parameters
Returns
- bool
true if the OneOf instances are equal; otherwise, false.
implicit operator OneOf<T1, T2, T3>(T1)
Implicit conversion from T1 to OneOf<T1, T2, T3>.
public static implicit operator OneOf<T1, T2, T3>(T1 value)
Parameters
valueT1The T1 value to convert.
Returns
- OneOf<T1, T2, T3>
A OneOf containing the T1 value.
Examples
OneOf<Error, Success, Warning> result = new NotFoundError(); // Implicit conversion
implicit operator OneOf<T1, T2, T3>(T2)
Implicit conversion from T2 to OneOf<T1, T2, T3>.
public static implicit operator OneOf<T1, T2, T3>(T2 value)
Parameters
valueT2The T2 value to convert.
Returns
- OneOf<T1, T2, T3>
A OneOf containing the T2 value.
Examples
OneOf<Error, Success, Warning> result = new Success("Data processed"); // Implicit conversion
implicit operator OneOf<T1, T2, T3>(T3)
Implicit conversion from T3 to OneOf<T1, T2, T3>.
public static implicit operator OneOf<T1, T2, T3>(T3 value)
Parameters
valueT3The T3 value to convert.
Returns
- OneOf<T1, T2, T3>
A OneOf containing the T3 value.
Examples
OneOf<Error, Success, Warning> result = new Warning("Deprecated API"); // Implicit conversion
operator !=(OneOf<T1, T2, T3>, OneOf<T1, T2, T3>)
Inequality operator for OneOf instances.
public static bool operator !=(OneOf<T1, T2, T3> left, OneOf<T1, T2, T3> right)
Parameters
Returns
- bool
true if the OneOf instances are not equal; otherwise, false.