基本的なことのようです...
これは、概念を理解するのは簡単ですが、実装するのはまったく簡単ではない (多くの) ものの 1 つです。
Oded の回答によると、.NET の属性は何もしません。それらは、他のコード (または開発者) が後でそれらを見ることができるようにのみ存在します。勝手なコメントと思ってください。
それを念頭に置いて、このように属性を書くことができます
public class AtomicAttribute : Attribute { }
ここで難しいのは、その属性をスキャンしてコードの動作を変更するコードを作成する必要があることです。
C# がコンパイル済み言語であり、.NET CLR の規則を考えると、これを行うには理論的に 3 つの方法があります。
C# コンパイラにフックし、その属性を認識したときに別のコードを出力するようにします。
これはいいことのように思えますが、今はまったく不可能です。将来的には
Roslyn
プロジェクトでこれが可能になるかもしれませんが、現時点ではできません。
C# コンパイラが MSIL に変換した後に .NET アセンブリをスキャンする何かを記述し、MSIL を変更します。
これは基本的にPostSharpが行うことです。MSIL のスキャンと書き換えは困難です。役立つMono.Cecilなどのライブラリがありますが、それでも非常に難しい問題です。また、デバッガなどに干渉する可能性があります。
.NET プロファイリング API を使用して実行中のプログラムを監視し、その属性を持つ関数呼び出しを確認するたびに、それを他のラッパー関数にリダイレクトします。
これはおそらく最も簡単なオプションですが (それでも非常に難しいですが)、プログラムをプロファイラーの下で実行する必要があるという欠点があります。これは開発用 PC では問題ないかもしれませんが、展開しようとすると大きな問題が発生します。また、このアプローチを使用すると、パフォーマンスが大幅に低下する可能性があります。
私の意見では、トランザクションをセットアップするラッパー関数を作成し、実際の作業を行うラムダを渡すことが最善の策です。このような:
public static class Ext
{
public static void Atomic(Action action)
{
using(var scope = new TransactionScope())
{
action();
scope.Commit();
}
}
}
.....
using static Ext; // as of VS2015
public void Foo()
{
Atomic(() => {
// foo logic
}
}
これに対する高度なコンピューター サイエンス用語は、高階プログラミングです。