🙌

C# 8 Pattern-matching

2020/10/11に公開

C# 8 でとうとうパターンマッチングが実装されたので、早速 rust っぽく Result<T> 型を実装してみました。

	public struct Result<T>
	{
		public readonly bool IsSuccess;
		public readonly T Value;
		public readonly string? Message;

		private Result(bool success, T value, string? message) =>
			(IsSuccess, Value, Message) = (success, value, message);

		public void Deconstruct(out bool success, out T value, out string? message) =>
			(success, value, message) = (IsSuccess, Value, Message);

		public static Result<T> Fail(string message) => new Result<T>(false, default, message);
		public static Result<T> Success(T value) => new Result<T>(true, value, null);
	}

こんな感じに使います。

    var tmp = SomeMethod() switch
    {
        (false, _, _) => throw new NotSupportedException(),
        (true, var value, _) => value 
    };

ただメッセージが欲しいが為につけてる message のせいであまり綺麗になってないのが難点…。Enum に対して対して値を持たせられないのでこうなるのは仕方ないかんじでしょうか。

ただ {} で指定すると必要のない値は無視できるんですが、如何せんメンバ名がごちゃごちゃして見づらい。

    // 位置指定
    switch (TryGetValue(ref input, ref length))
    {
        case (false, _, var e):
            return Result<JsonNode>.Fail(e);
        case (true, var value, _):
            values.Add(value);
            break;
    }

    // メンバ指定
    switch (TryGetValue(ref input, ref length))
    {
        case {IsSuccess:false, Message: var e}:
            return Result<JsonNode>.Fail(e);
        case {IsSuccess:true, Value: var value}:
            values.Add(value);
            break;
    }

お役に立てましたらライク、サポートしていただけますと嬉しいです!🙇🙇

Discussion