Last active
March 15, 2020 13:43
-
-
Save gunters63/6381c43dd0ee29aa813985303bf70120 to your computer and use it in GitHub Desktop.
Immutable classes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ConsoleApp2 | |
{ | |
public class Fruit2 | |
{ | |
public string Color { get; } | |
public int SkinThickness { get; } | |
public static Fruit2 Create(Optional<string> color = default, Optional<int> skinThickness = default) | |
{ | |
return DefaultInstance.With( | |
color: Optional.For(value: color.GetValueOrDefault(defaultValue: DefaultInstance.Color)), | |
skinThickness: Optional.For(value: skinThickness.GetValueOrDefault(defaultValue: DefaultInstance.SkinThickness)) | |
); | |
} | |
public Fruit2 ChangeColor(string newColor) | |
{ | |
if (newColor == Color) | |
return this; | |
// Generate domain event | |
return With(color: newColor); | |
} | |
private Fruit2(string color, int skinThickness) | |
{ | |
Color = color; | |
SkinThickness = skinThickness; | |
} | |
private static Fruit2 GetDefault() | |
{ | |
return new Fruit2(color: string.Empty, 0); | |
} | |
private static readonly Fruit2 DefaultInstance = GetDefault(); | |
private Fruit2 With(Optional<string> color = default, Optional<int> skinThickness = default) | |
{ | |
return new Fruit2( | |
color: color.GetValueOrDefault(defaultValue: Color), | |
skinThickness: skinThickness.GetValueOrDefault(defaultValue: SkinThickness)); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Diagnostics; | |
namespace ConsoleApp2 | |
{ | |
public static class Optional | |
{ | |
[DebuggerStepThrough] | |
public static Optional<T> For<T>(T value) | |
{ | |
return value; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Diagnostics; | |
namespace ConsoleApp2 | |
{ | |
/// <summary> | |
/// A wrapper around optional parameters to capture whether they were specified or omitted. | |
/// An implicit operator is defined so no one has to explicitly create this struct. | |
/// </summary> | |
[DebuggerDisplay(value: "{IsDefined ? Value.ToString() : \"<missing>\",nq}")] | |
public struct Optional<T> | |
{ | |
/// <summary> | |
/// Initializes a new instance of the <see cref="Optional{T}"/> struct. | |
/// </summary> | |
/// <param name="value">The value to specify.</param> | |
[DebuggerStepThrough] | |
public Optional(T value) | |
{ | |
IsDefined = true; | |
Value = value; | |
} | |
/// <summary> | |
/// Gets an instance that indicates the value was not specified. | |
/// </summary> | |
public static Optional<T> Missing | |
{ | |
[DebuggerStepThrough] | |
get => new Optional<T>(); | |
} | |
/// <summary> | |
/// Gets a value indicating whether the value was specified. | |
/// </summary> | |
public bool IsDefined { [DebuggerStepThrough] get; } | |
/// <summary> | |
/// Gets the specified value, or the default value for the type if <see cref="IsDefined"/> is <c>false</c>. | |
/// </summary> | |
public T Value { [DebuggerStepThrough] get; } | |
/// <summary> | |
/// Implicitly wraps the specified value as an Optional. | |
/// </summary> | |
[DebuggerStepThrough] | |
public static implicit operator Optional<T>(T value) | |
{ | |
return new Optional<T>(value); | |
} | |
/// <summary> | |
/// Gets the value that was given, or the specified fallback value if <see cref="IsDefined"/> is <c>false</c>. | |
/// </summary> | |
/// <param name="defaultValue">The default value to use if a value was not specified.</param> | |
/// <returns>The value.</returns> | |
[DebuggerStepThrough] | |
public T GetValueOrDefault(T defaultValue) | |
{ | |
return IsDefined ? Value : defaultValue; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment