Skip to content

Instantly share code, notes, and snippets.

@HamedFathi
Forked from DevWouter/wrapping.cs
Created November 9, 2021 22:32
Show Gist options
  • Save HamedFathi/3da0a3495ed39ad78829693de19adfd3 to your computer and use it in GitHub Desktop.
Save HamedFathi/3da0a3495ed39ad78829693de19adfd3 to your computer and use it in GitHub Desktop.
using System;
namespace Dummy
{
class Program
{
private static void Header(string title)
{
Console.WriteLine(new string('=', 79));
Console.WriteLine(title);
Console.WriteLine(new string('=', 79));
}
static void Main()
{
WrapValue<string>.DefaultValue = "missing-name";
var withValue = new WrapValue<string>("Wouter");
var withoutValue = new WrapValue<string>();
Header("Without handling");
Console.WriteLine("My name is {0}", withValue);
Console.WriteLine("My name is {0}", withoutValue);
Header("With handling");
WrapValue<string>.MissingValueHandler = _ =>
Console.WriteLine("WARNING: Returning default value because no actual value");
Console.WriteLine("My name is {0}", withValue);
Console.WriteLine("My name is {0}", withoutValue);
try
{
Header("With exception management");
WrapValue<string>.MissingValueHandler = _ =>
throw new Exception($"Returning default value because no actual value");
Console.WriteLine("My name is {0}", withValue);
Console.WriteLine("My name is {0}", withoutValue);
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex);
}
// The downsides:
// 1. The MissingValueHandler and Default value are static to the type and not the field but that can easily
// by providing a parent and a type name.
// 2. This approach hides things from the developer that uses it, making it harder to debug (and I don't like that)
}
public class WrapValue<T>
{
public bool HasValue { get; }
public T ActualValue { get; }
public static T DefaultValue { get; set; }
public static Action<WrapValue<T>> MissingValueHandler { get; set; } = _ => { };
public WrapValue(T value)
{
ActualValue = value;
HasValue = true;
}
public WrapValue()
{
HasValue = false;
}
public static implicit operator WrapValue<T>(T value)
{
return new WrapValue<T>(value);
}
public static implicit operator T(WrapValue<T> d)
{
if (d.HasValue)
{
return d.ActualValue;
}
MissingValueHandler(d);
return DefaultValue;
}
public override string ToString()
{
// ReSharper disable once RedundantCast because it's not redundant since we don't want "WrapValue`1[T]"
return ((T)this).ToString();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment