C#で条件付きコンパイルを使用するコードを使用する代わりに何ができますか?
#ifdefに基づくコードがたくさんあるクラスがあります..しばらくすると、コードが読めなくなります。
#if
多くの定義を持つコードの読みやすさとメンテナンスを向上させるために使用するリファクタリング手法を探しています
C#で条件付きコンパイルを使用するコードを使用する代わりに何ができますか?
#ifdefに基づくコードがたくさんあるクラスがあります..しばらくすると、コードが読めなくなります。
#if
多くの定義を持つコードの読みやすさとメンテナンスを向上させるために使用するリファクタリング手法を探しています
ConditionalAttribute
1つは、 :を使用することです。
[Conditional("DEBUG")]
public void Foo()
{
// Stuff
}
// This call will only be compiled into the code if the DEBUG symbol is defined
Foo();
これはまだ条件付きコンパイルですが、ではなく属性に基づいて#ifdef
いるため、一般的に簡単です。
もう1つの方法は、コンパイル時にすべてを実行するのではなく、実行時にブール値を使用することです。達成しようとしていることと、条件付きコンパイルをどのように使用しているかについて、詳細を教えていただければ便利です。
別の方法は、 ConditionalAttributeを使用することです。条件付き属性も同様に機能します。
#define TRACE_ON
using System;
using System.Diagnostics;
public class Trace
{
[Conditional("TRACE_ON")]
public static void Msg(string msg)
{
Console.WriteLine(msg);
}
}
public class ProgramClass
{
static void Main()
{
Trace.Msg("Now in Main...");
Console.WriteLine("Done.");
}
}
コードの可読性の問題である場合は、.Netの部分クラス修飾子を使用して、条件付きコードを別々のファイルに配置することを検討してください。そのため、次のようなものが考えられます...
foo.cs:
public partial class Foo
{
// Shared Behavior
}
foo.Debug.cs:
#if DEBUG
public partial class Foo
{
// debug Behavior
}
#endif
foo.bar.cs:
#define BAR
#if BAR
public partial class Foo
{
// special "BAR" Behavior
}
#endif
ただし、コードファイルの外部で条件を定義できるかどうかはわかりません。そのため、このような操作を行うと、条件定義の柔軟性が低下する可能性があります(たとえば、BARに対して条件分岐を作成できない場合があります。 、メインファイル、および複数の定義されたBARを維持する必要があると、醜くなる可能性があります)、また、コードのそのビットを効果的に有効/無効にするために、ファイルに移動するために特定の注意が必要です。
したがって、このアプローチを使用すると、解決するよりも多くの問題が発生する可能性がありますが、コードによっては、役立つ可能性がありますか?
ポリモーフィズム。
同じ条件で条件分岐がたくさんあるスパゲッティコードと同じようにアプローチします。
違いを基本クラスまたはインターフェースに抽象化します。
ビルドに応じて具象クラスを構築します(1つの#if)。具体的なオブジェクトをアプリに渡すと、アプリはインターフェースで定義されたメソッドを呼び出します。
ConditionalAttributeを使用することから始めます。そうでなければ、条件付きコンパイルで人々がよく行うことのかなりの部分は、通常、制御の反転および/またはファクトリの賢明な使用によって処理できます。
条件付きコンパイルを使用している理由を簡単にリファクタリングできる場合は、Managed Extensibility Frameworkを使用して、実行時の条件に基づいてコードを動的にロードすることを検討してください。
Jonの答えを拡張すると、の使用にはいくつかの制限がConditionalAttribute
ありますが、大きな利点があります。条件がfalseの場合、条件付きメソッドの呼び出しは省略されます。たとえば、デバッグのために、ログシステムに数百の呼び出しを追加できます。これは、本番コードから条件付きで除外できます。それらが除外されると、呼び出す必要のないメソッドの呼び出しに関連するオーバーヘッドはありません。#ifdefを使用すると、ログシステムへのすべての呼び出しをラップして、条件付きでそれらを除外する必要があります。
これは、条件付きメソッドの呼び出し元が再コンパイルされた場合にのみ、アセンブリ間で機能することに注意してください。