Skip to content

Instantly share code, notes, and snippets.

@zakky-dev
Last active August 29, 2015 14:06
Show Gist options
  • Save zakky-dev/56f592e6209cd6ca9c6d to your computer and use it in GitHub Desktop.
Save zakky-dev/56f592e6209cd6ca9c6d to your computer and use it in GitHub Desktop.
try-catch-finallyの式化やってみた
using System;
using System.Collections.Generic;
namespace Expression
{
public static class Expression
{
public static ETry<TResult> Try<TResult>(Func<TResult> tryBlock)
{
return new ETry<TResult>(tryBlock);
}
public class ETry<TResult>
{
private Func<TResult> tryBlock;
internal ETry(Func<TResult> block)
{
tryBlock = block;
}
internal EWith<TResult> With<HandlingException>(Func<HandlingException, TResult> block)
where HandlingException : Exception
{
return EWith<TResult>.Create<HandlingException>(tryBlock, block);
}
internal EFinally<TResult> Finally(Action block)
{
return new EFinally<TResult>(tryBlock, block);
}
}
public class EWith<TResult>
{
private Func<TResult> tryWithBlock;
private bool isCached = false;
private EWith(Func<TResult> tryBlock)
{
tryWithBlock = tryBlock;
}
internal static EWith<TResult> Create<HandlingException>(Func<TResult> tryBlock, Func<HandlingException, TResult> withBlock)
where HandlingException : Exception
{
return new EWith<TResult>(tryBlock).With<HandlingException>(withBlock);
}
internal EWith<TResult> With<HandlingException>(Func<HandlingException, TResult> block)
where HandlingException : Exception
{
var child = tryWithBlock;
tryWithBlock = () =>
{
try
{
return child();
}
catch (HandlingException exn)
{
if (!isCached)
{
isCached = true;
return block(exn);
}
throw;
}
};
return this;
}
internal EFinally<TResult> Finally(Action block)
{
return new EFinally<TResult>(tryWithBlock, block);
}
public static implicit operator TResult(EWith<TResult> self)
{
return self.tryWithBlock();
}
}
public class EFinally<TResult>
{
private Func<TResult> block;
internal EFinally(Func<TResult> tryBlock, Action finallyBlock)
{
block = () =>
{
try
{
return tryBlock();
}
finally
{
finallyBlock();
}
};
}
public static implicit operator TResult(EFinally<TResult> self)
{
return self.block();
}
}
}
class Program
{
static void Main(string[] args)
{
var ls = new List<string>();
int ret =
Expression.Try(() => { ls.Add("try"); throw new InvalidCastException(""); return ls.Count; })
.With<InvalidCastException>(exn => { ls.Add("with InvalidCastException"); return ls.Count; })
.With<InvalidOperationException>(exn => { ls.Add("with InvalidOperationException"); return ls.Count; })
.With<Exception>(exn => { ls.Add("with Exception"); return ls.Count; })
.Finally(() => ls.Add("finally"));
Console.WriteLine(ret);
foreach (var l in ls)
{
Console.WriteLine(l);
}
Console.ReadKey(false);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment