私はいくつかの変数がプロジェクト全体でグローバルであり、すべての形式でアクセス可能であることを望んでいます。これどうやってするの?
はい、静的クラスを使用してできます。このような:
static class Global
{
private static string _globalVar = "";
public static string GlobalVar
{
get { return _globalVar; }
set { _globalVar = value; }
}
}
そして、あなたが書くことができる場所を使うために:
GlobalClass.GlobalVar = "any string value"
または、グローバルを app.config に入れることもできます
静的クラス または シングルトンパターン を使用できます。
一方通行、
ソリューションエクスプローラー>プロジェクト>プロパティ> Settings.Settings。このファイルをクリックして、IDEから設定の定義を追加します。
にアクセスする
Properties.Settings.Default.MySetting = "hello world";
ここでのコンセンサスは、グローバル変数を静的メンバーとして静的クラスに入れることです。新しいWindowsフォームアプリケーションを作成すると、通常、プログラムクラス(Program.cs)が付属します。これは静的クラスであり、アプリケーションのメインエントリポイントとして機能します。アプリの存続期間全体にわたって有効であるため、新しい変数を作成するのではなく、グローバル変数をそこに配置するのが最善だと思います。
static class Program
{
public static string globalString = "This is a global string.";
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
そして、次のように使用します:
public partial class Form1 : Form
{
public Form1()
{
Program.globalString = "Accessible in Form1.";
InitializeComponent();
}
}
public static class MyGlobals
{
public static string Global1 = "Hello";
public static string Global2 = "World";
}
public class Foo
{
private void Method1()
{
string example = MyGlobals.Global1;
//etc
}
}
彼らはすでにグローバル変数の使用方法に答えています。
スペイン語のstackoverflowで実行される question の結果、グローバル変数の使用が悪い考えである理由を説明します。
スペイン語のテキストの明示的な翻訳:
グローバル変数の問題は、隠された依存関係を作成することです。大規模なアプリケーションに関しては、自分自身が知らない/覚えていない/自分が持っているオブジェクトとその関係についてはっきりしている。
そのため、グローバル変数が使用しているオブジェクトの数を明確に把握することはできません。そして、たとえば、可能性のある各値の意味やタイプなど、グローバル変数の何かを変更したい場合は?その変更は何個のクラスまたはコンパイル単位に影響しますか?金額が少ない場合は、変更する価値があります。影響が大きい場合は、別のソリューションを探す価値があるかもしれません。
しかし、その影響は何ですか?グローバル変数はコード内のどこでも使用できるため、測定するのは非常に困難です。
さらに、変数を使用するコードの量が可能な限り少なくなるように、可能な限り短いライフタイムの変数を常に使用するようにしてください。したがって、その目的と変更者をよりよく理解します。
グローバル変数はプログラムの期間中持続するため、だれでも変数を使用して読み取り、さらに悪いことにその値を変更することができ、特定のプログラムで変数がどのような値を持つかを知ることがより困難になりますポイント。 。
別の問題は破壊の順序です。変数は、ローカル変数またはグローバル/静的変数であるかどうかにかかわらず、常に作成の逆の順序で破棄されます(例外はプリミティブ型、int
、enum
sなどです。それらはプログラムを終了するまでグローバル/静的です)。
問題は、グローバル(または静的)変数の構築順序を知ることが難しいことです。原則として、それは不確定です。
すべてのグローバル変数/静的変数が単一のコンパイル単位にある場合(つまり、.cpp
のみ)、構築の順序は書き込みの順序と同じです(つまり、以前に定義された変数が構築されます)前)。
しかし、それぞれが独自のグローバル/静的変数を持つ複数の.cpp
がある場合、グローバルな構築順序は不確定です。もちろん、各コンパイル単位(各.cpp
)の順序は特に尊重されます。グローバル変数A
がB
、A
の前に定義されている場合B
の前に構築されますが、他の.cpp
のA
とB
変数の間で初期化される可能性があります。たとえば、次のグローバル/静的変数を持つ3つのユニットがある場合:
実行可能ファイルでは、この順序で(または各.cpp
内で相対的な順序が守られている限り、他の順序で)作成できます。
何でこれが大切ですか?異なる静的グローバルオブジェクト間にリレーションがある場合、たとえば、一部のデストラクタで、他のグローバル変数のデストラクタで他のオブジェクトを使用する場合、すでに破棄されていることが判明した別のコンパイルユニットの別のグローバルオブジェクトを使用するため後で構築されます)。
この例で使用するソースを見つけようとしましたが、見つかりません(とにかく、例はグローバル変数と静的変数に適用できますが、シングルトンの使用を例示するためでした)。非表示の依存関係は、グローバル変数の状態に依存する場合、オブジェクトの動作の制御に関連する新しい問題も作成します。
支払いシステムがあり、変更を加える必要があり、コードが他の人(または数年前のもの)のものであるため、支払いシステムをテストして、どのように機能するかを想像してください。新しいmain
を開き、銀行支払いサービスにカードを提供するグローバルオブジェクトの対応する関数を呼び出します。すると、データを入力すると請求されます。簡単なテストで、製品版をどのように使用しましたか?簡単な支払いテストを行うにはどうすればよいですか?
他の同僚に尋ねた後、収集プロセスを開始する前に、テストモードにあるかどうかを示すグローバルブールである「true」をマークする必要があることがわかりました。支払いサービスを提供するオブジェクトは、支払い方法を提供する別のオブジェクトに依存し、その依存関係はプログラマーには見えない方法で発生します。
言い換えれば、グローバル変数(またはシングルトーン)は、「テスト」インスタンスに置き換えられないため、「テストモード」に渡すことを不可能にします(コードが作成または定義されているコードを変更しない限り)。グローバル変数ですが、テストはマザーコードを変更せずに行われると想定しています)。
これは、*依存性注入*と呼ばれるものによって解決されます。これは、オブジェクトがコンストラクターまたは対応するメソッドで必要とするすべての依存性をパラメーターとして渡すことにあります。このように、プログラマーはコードを記述しなければならないため、開発者が多くの時間を稼ぐことができるので、**自分に何が起きなければならないのかを理解します。
グローバルオブジェクトが多すぎて、それらを必要とする関数のパラメーターが多すぎる場合は、「グローバルオブジェクト」のインスタンスを構築して返すクラス*スタイル*ファクトリ*に「グローバルオブジェクト」をいつでもグループ化できます。 "(シミュレートされた)必要に応じて、ファクトリをパラメーターとして、グローバルオブジェクトを依存関係として必要とするオブジェクトに渡します。
テストモードに渡す場合は、常にテストファクトリ(同じオブジェクトの異なるバージョンを返す)を作成し、ターゲットクラスを変更せずにパラメーターとして渡すことができます。
必ずしも、グローバル変数の適切な使用法があるとは限りません。たとえば、定数値(PI値)。定数値であるため、プログラム内の特定のポイントで、別のモジュールからの任意のタイプの変更によってその値を知らないというリスクはありません。さらに、定数値はプリミティブになる傾向があり、その定義を変更することはほとんどありません。
この場合、グローバル変数を使用すると、変数をパラメーターとして渡す必要がなくなり、関数のシグネチャが簡素化されます。
もう1つは、ログクラス(通常はオプションであり、プログラムで構成可能であり、したがってアプリケーションの核の動作に影響を与えないファイルで発生することを保存する)などの非侵入型の「グローバル」サービス、またはstd :: cout
、std :: cin
またはstd :: cerr
。これらもグローバルオブジェクトです。
他のものは、たとえその寿命がプログラムの寿命とほぼ一致していても、常にパラメーターとして渡します。変数はモジュール内でグローバルであり、他のアクセス権を持たない場合にのみ可能ですが、いずれにしても、依存関係は常にパラメーターとして存在します。
回答: Peregring-lk
Visual C#を使用している場合、行う必要があるのは、Formを継承するProgram.csにクラスを追加し、すべてのForm * .csですべての継承クラスをFormから自分のクラスに変更することだけです。
//Program.cs
public class Forms : Form
{
//Declare your global valuables here.
}
//Form1.cs
public partial class Form1 : Forms //Change from Form to Forms
{
//...
}
もちろん、 クラスFormを変更せずに拡張する にする方法があります。その場合は、拡張するだけです!すべてのフォームがデフォルトで継承しているため、その中で宣言されているすべての貴重品は自動的にグローバルになります!幸運を!!!