StoryQ.Formatting名前空間を調べるように案内してくれたGiorgio Minardiに感謝します。そこで、単純な属性を使用してメソッドのフォーマットをオーバーライドできることを発見しました。
API はOverrideMethodFormatAttribute
(抽象クラスからサブクラス化されたMethodFormatAttribute
) を提供します。これは、特定の文字列定数を使用する場合に機能しますが、C# は属性内のメソッドの型パラメーターが好きではありません。これは、属性が原因でコンパイルされませんT
:
[OverrideMethodFormat(string.Format("exception is thrown ({0})", typeof(T).Name))]
private void ExceptionIsThrown<T>() where T : Exception
{
...
}
MethodFormatAttribute
解決策は、ジェネリック型のメソッドを具体的に検索して出力する別のサブクラスを作成することです。このサブクラスは以下のとおりです。
public class GenericMethodFormatAttribute : MethodFormatAttribute
{
private readonly string _textFormat;
public GenericMethodFormatAttribute()
{
_textFormat = null;
}
public GenericMethodFormatAttribute(string textFormat)
{
_textFormat = textFormat;
}
public override string Format(MethodInfo method,
IEnumerable<string> parameters)
{
var generics = method.GetGenericArguments();
if (_textFormat == null)
{
var genericsList = string.Join<Type>(", ", generics);
return string.Format("{0} ({1})",
UnCamel(method.Name),
genericsList);
}
return string.Format(_textFormat, generics);
}
}
使用方法は、オプションで文字列定数の代わりにフォーマット文字列を指定することを除いて、指定された属性とほとんど同じです。フォーマット文字列を省略すると、デフォルトの動作と同様に、メソッド名のキャメル ケースが解除されます。
[GenericMethodFormatAttribute]
private void ExceptionIsThrown<T>() where T : Exception
{
...
}
これにより、StoryQ コードに手を加えることなく、ソースで属性を宣言できます。拡張性のためのStoryQへの10ポイント!