Written by
on
on
例外を吐くコンストラクタの切り替え on C#
課題
下記のように、同じinterfaceを持つ複数のクラスがあるとします。
public interface Hogehoge
{
void Say();
}
public class Foo : Hogehoge
{
int i { get; }
public Foo(int i)
{
if (i > 10)
{
throw new Exception();
}
this.i = i;
}
public void Say()
{
Console.WriteLine($"Foo:{i}");
}
}
public class Bar : Hogehoge
{
int i { get; }
public Bar(int i)
{
if (i <= 10)
{
throw new Exception();
}
this.i = i;
}
public void Say()
{
Console.WriteLine($"Bar:{i}");
}
}
このインスタンスを、例外に応じて切り替えるみたいな書き方をすることがあります。
using System;
public class Hello
{
public static void Main()
{
// Your code here!
const int i = 15;
Hogehoge x;
try
{
x = new Foo(i);
}
catch
{
x = new Bar(i);
}
x.Say();
System.Console.WriteLine("Hello C#");
}
}
このtry~catch部分を短く書く方法を考えます。
拡張メソッドの使用
下記の拡張メソッドを用意します。
public static class MyExtensions
{
public static bool TryConstruct<T>(Func<T> TConstructor, out T result) where T : class
{
try
{
result = TConstructor();
return true;
}
catch
{
result = null;
return false;
}
}
}
これを使うと先ほどのMainはかなり短く書けて、
public class Hello
{
public static void Main()
{
// Your code here!
const int i = 15;
var x = (MyExtensions.TryConstruct<Hogehoge>(() => new Foo(i), out var tmp)) ? tmp : new Bar(i);
x.Say();
}
}
じゃあ実際に使うか、といわれると読みにくいので使わないです。いいアイディアあったら教えてください。