WinForms – Variáveis ​​Globais

Eu quero que algumas variables ​​sejam globais em todo o projeto e acessíveis em todas as formas. Como posso fazer isso?

sim você pode usar class estática. como isso:

static class Global { private static string _globalVar = ""; public static string GlobalVar { get { return _globalVar; } set { _globalVar = value; } } } 

e para usar qualquer lugar onde você possa escrever:

 GlobalClass.GlobalVar = "any string value" 

Ou você poderia colocar seus globals no app.config

Você pode usar class estática ou padrão Singleton .

Mão única,

Solution Explorer> Seu Projeto> Propriedades> Configurações.Settings. Clique neste arquivo e adicione suas configurações no IDE.

Acesse-os por

 Properties.Settings.Default.MySetting = "hello world"; 
 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 } } 

O consenso aqui é colocar as variables ​​globais em uma class estática como membros estáticos. Quando você cria um novo aplicativo Windows Forms, ele geralmente vem com uma class de programa (Program.cs), que é uma class estática e serve como o principal ponto de input do aplicativo. Ele vive durante toda a vida útil do aplicativo, então acho que é melhor colocar as variables ​​globais lá em vez de criar uma nova.

 static class Program { public static string globalString = "This is a global string."; ///  /// The main entry point for the application. ///  [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } 

E use como tal:

 public partial class Form1 : Form { public Form1() { Program.globalString = "Accessible in Form1."; InitializeComponent(); } } 

Se você estiver usando o Visual C #, tudo o que você precisa fazer é adicionar uma class ao Program.cs herdando o Form e alterar toda a class herdada de Form para sua class em cada Form * .cs.

 //Program.cs public class Forms : Form { //Declare your global valuables here. } //Form1.cs public partial class Form1 : Forms //Change from Form to Forms { //... } 

Claro, pode haver uma maneira de estender a class Form sem modificá-la . Se for esse o caso, tudo que você precisa fazer é estendê-lo! Como todas as formas estão herdando-as por padrão, todos os objects de valor declarados se tornarão globais automaticamente! Boa sorte!!!

Eles já responderam como usar uma variável global.

Eu vou te dizer porque o uso de variables ​​globais é uma má idéia como resultado desta questão realizada em stackoverflow em espanhol.

Tradução explícita do texto em espanhol:

Impacto da mudança

O problema com as variables ​​globais é que elas criam dependencies ocultas. Quando se trata de aplicativos grandes, você mesmo não sabe / lembra / está claro sobre os objects que você tem e seus relacionamentos.

Portanto, você não pode ter uma noção clara de quantos objects sua variável global está usando. E se você quiser alterar algo da variável global, por exemplo, o significado de cada um dos seus valores possíveis, ou seu tipo? Quantas classs ou unidades de compilation essa mudança afetará? Se o valor for pequeno, pode valer a pena fazer a alteração. Se o impacto for grande, pode valer a pena procurar outra solução.

Mas qual é o impacto? Como uma variável global pode ser usada em qualquer parte do código, pode ser muito difícil medi-la.

Além disso, sempre tente ter uma variável com o menor tempo de vida possível, para que a quantidade de código que faz uso dessa variável seja o mínimo possível e, assim, compreenda melhor sua finalidade e quem a modifica.

Uma variável global dura a duração do programa e, portanto, qualquer um pode usar a variável, seja para lê-la, ou pior, para alterar seu valor, tornando mais difícil saber qual valor a variável terá em qualquer programa ponto. .

Ordem de destruição

Outro problema é a ordem de destruição. As variables ​​são sempre destruídas na ordem inversa de sua criação, sejam elas locais ou globais / variables ​​estáticas (uma exceção são os tipos primitivos, int , enum s, etc., que nunca são destruídos se forem globais / estáticos até terminarem o programa).

O problema é que é difícil saber a ordem de construção das variables ​​globais (ou estáticas). Em princípio, é indeterminado.

Se todas as suas variables ​​globais / estáticas estiverem em uma única unidade de compilation (isto é, você só tem um .cpp ), a ordem de construção é a mesma que a da escrita (isto é, variables ​​definidas antes, são construídas antes).

Mas se você tiver mais de um .cpp com suas próprias variables ​​globais / estáticas, a ordem de construção global é indeterminada. Naturalmente, a ordem em cada unidade de compilation (cada .cpp ) em particular, é respeitada: se a variável global A é definida antes de B , A será construído antes de B , mas é possível que entre variables A e B de outro .cpp são inicializados. Por exemplo, se você tiver três unidades com as seguintes variables ​​globais / estáticas:

Image1

No executável, pode ser criado nesta ordem (ou em qualquer outra ordem, desde que a ordem relativa seja respeitada dentro de cada .cpp ):

Image2

Por que isso é importante? Porque se existem relações entre diferentes objects globais estáticos, por exemplo, que alguns usam outros em seus destruidores, talvez, no destruidor de uma variável global, você use outro object global de outra unidade de compilation que acaba por ser destruída (tem foi construído mais tarde).

Dependências ocultas e * casos de teste *

Eu tentei encontrar a fonte que vou usar neste exemplo, mas não consigo encontrá-lo (de qualquer forma, foi para exemplificar o uso de singletons, embora o exemplo seja aplicável a variables ​​globais e estáticas). Dependências ocultas também criam novos problemas relacionados ao controle do comportamento de um object, se depender do estado de uma variável global.

Imagine que você tenha um sistema de pagamento e queira testá-lo para ver como ele funciona, já que você precisa fazer alterações, e o código é de outra pessoa (ou sua, mas de alguns anos atrás). Você abre um novo main e chama a function correspondente do seu object global que fornece um serviço de pagamento bancário com um cartão, e acontece que você insere seus dados e eles cobram de você. Como, em um teste simples, usei uma versão de produção? Como posso fazer um teste de pagamento simples?

Depois de perguntar a outros colegas de trabalho, você precisa “marcar true”, um bool global que indica se estamos no modo de teste ou não, antes de iniciar o processo de coleta. Seu object que fornece o serviço de pagamento depende de outro object que fornece o modo de pagamento, e essa dependência ocorre de maneira invisível para o programador.

Em outras palavras, as variables ​​globais (ou singletones) tornam impossível passar para o “modo de teste”, já que variables ​​globais não podem ser substituídas por instâncias de “teste” (a menos que você modifique o código onde o código é criado ou definido). variável global, mas assumimos que os testes são feitos sem modificar o código-mãe).

Solução

Isto é resolvido por meio do que é chamado * * injeção de dependência, que consiste em passar como parâmetro todas as dependencies que um object precisa em seu construtor ou no método correspondente. Desta forma, o programador ** vê ** o que tem que acontecer com ele, já que ele tem que escrevê-lo em código, fazendo com que os desenvolvedores ganhem muito tempo.

Se houver muitos objects globais e houver muitos parâmetros nas funções que precisam deles, você sempre poderá agrupar seus “objects globais” em uma class, estilo * factory *, que cria e retorna a instância do “object global”. “(simulado) que você quer, passando a fábrica como um parâmetro para os objects que precisam do object global como dependência.

Se você passar para o modo de teste, poderá sempre criar uma fábrica de testes (que retorna diferentes versões dos mesmos objects) e passá-la como um parâmetro sem ter que modificar a class de destino.

Mas é sempre ruim?

Não necessariamente, pode haver bons usos para variables ​​globais. Por exemplo, valores constantes (o valor do PI). Sendo um valor constante, não há risco de não conhecer seu valor em um determinado ponto no programa por qualquer tipo de modificação de outro módulo. Além disso, os valores constantes tendem a ser primitivos e é improvável que alterem sua definição.

É mais conveniente, neste caso, usar variables ​​globais para evitar ter que passar as variables ​​como parâmetros, simplificando as assinaturas das funções.

Outro pode ser serviços “globais” não intrusivos, como uma class de registro (salvando o que acontece em um arquivo, que geralmente é opcional e configurável em um programa e, portanto, não afeta o comportamento nuclear do aplicativo), ou std :: cout , std :: cin ou std :: cerr , que também são objects globais.

Qualquer outra coisa, mesmo que seu tempo de vida coincida quase com o do programa, sempre passe como parâmetro. Mesmo a variável poderia ser global em um módulo, somente nela sem que qualquer outra tenha access, mas que, em qualquer caso, as dependencies estão sempre presentes como parâmetros.

Resposta por: Peregring-lk