2009-05-21 26 views
8

Sono abituato ai linguaggi di scripting. PHP, Javascript ecc. E ho scritto alcune applicazioni Java e C# relativamente semplici. Questa è una domanda per cui ho più volte avuto bisogno di una risposta, e immagino di non essere l'unica.Come posso mantenere i dati senza variabili globali?

Diciamo che sono in Javascript.

Ho la funzione A(), chiamata dalla GUI, che recupera qualche valore.

La funzione B(), chiamata anche dalla GUI, richiede tale valore, ma la funzione B() verrà chiamata un numero arbitrario di volte, una lunghezza arbitraria di tempo dopo A().

Non desidero A() ricalcolare il valore ogni volta.

Un esempio sono le credenziali di accesso. A() richiede un nome utente e B() usa quel valore per aggiungere un log ogni volta che viene chiamato.

Per questo probabilmente utilizzerei solo una variabile globale.

Ora, C#. Nessuna variabile globale! Come dovrei fare questo?

Modifica: Godere delle risposte, ma ci sono molti commenti "prova a non usare globali". Che capisco, ma mi piacerebbe sentire i modelli alternativi per questo requisito.

+2

Si potrebbe prendere in considerazione la lettura di "memoization", che è il nome per la tecnica generale di ricordare quale era l'output di una funzione e riutilizzarla in seguito senza ricalcolarla. Esistono molte tecniche interessanti per la memoizzazione efficiente. –

risposta

4

In primo luogo, chiediti sempre se hai davvero bisogno di avere un globale, spesso non lo farai. Ma se si hanno veramente avere un ...

Il modo migliore per farlo è quello di avere una proprietà statica in qualche classe sensibilmente il nome, diventa efficace la vostra variabile globale

public class Credentials 
{ 
    public static string Username {get;set;} 
} 

//...somewhere in your code 

Credentials.Username = "MyUserName"; 

EDIT:

Un paio di persone hanno affermato che le variabili globali sono cattive, e sono d'accordo con questo sentimento, e sembrerebbe che anche i progettisti di C# siano d'accordo poiché semplicemente non sono disponibili.

Dovremmo tuttavia considerare i motivi per cui i Globali sono cattivi, e sono per la maggior parte considerati cattivi perché infrangono le regole dell'incapsulamento. I dati statici, tuttavia, non sono necessariamente dannosi, la cosa buona dei dati statici è che puoi incapsularli, il mio esempio sopra è un esempio molto semplicistico di ciò, probabilmente in uno scenario reale dovresti includere i tuoi dati statici nella stessa classe che altro lavoro con le credenziali, forse una classe di accesso o una classe utente o qualsiasi altra cosa abbia senso per la tua app.

+0

Vorrei sottolineare con forza: NON usare le cifre globali :) Tuttavia, se insisti, questo è un buon modo per farlo. –

+0

@Marcel: C# non ha numeri globali. – Brian

+0

Grazie per la risposta Tim. Marcel - per questo requisito, cosa suggeriresti di fare invece? – ChristianLinnell

0

In C#, uno dei modi per ottenere un comportamento simile alle variabili globali consiste nell'utilizzare metodi di classe statici e variabili di classe. I metodi e le variabili di classe statici hanno una singola istanza in C# e sono in qualche modo simili alle variabili globali in altre lingue.

Detto questo, per il tuo problema, sembra molto più un problema di progettazione. C# è molto focalizzato sulla progettazione orientata agli oggetti; Sospetto per il problema che hai dato che un OOD migliore avrebbe risolto il tuo problema.

5

Questa non è una buona pratica, ma se si ha realmente bisogno, c'è un certo numero di modi:

  1. applicazioni Web: È possibile inserire la variabile in un certo tipo di contesto, come la sessione o la ambito di applicazione.
  2. App desktop: è possibile creare un oggetto e memorizzarlo come una proprietà di una classe che ha sempre un oggetto attivo.
  3. Qualsiasi tipo di app: utilizzare una proprietà statica pubblica. È visibile a tutti.
+0

Grazie per la risposta ... quindi quale buona pratica suggeriresti invece? – ChristianLinnell

+0

Cambia il tuo design per allinearlo meglio al paradigma del design della lingua che hai scelto! – tomfanning

0

La funzione A fa parte di una classe (chiamarla C). La funzione A potrebbe quindi memorizzare le credenziali di accesso e fornire una funzione (o in C#, una proprietà) per ottenere le credenziali. Quando sono richiesti, è sufficiente utilizzare la proprietà per ottenere le credenziali archiviate e trasferirle nella funzione B (su una classe diversa).

class C 
{ 
    public void functionA() 
    { 
     credentials = obtainCredentials; 
    } 

    private LogonCredentials _logonCredentials = null; 

    public LogonCredentials logonCredentials 
    { 
     get { return _logonCredentials; } 
    } 
} 

class D 
{ 
    public void functionB(LogonCredentials credentials) 
    { 
     //do stuff 
    } 
} 

///other stuff 
///other function ... 
    ... 
    instanceC = C(); 
    instanceC.functionA(); 
    ///more stuff here 
    instangeD = D(); 
    instanceD.functionB(instanceC.logonCredentials); 
1

Direi che probabilmente dovresti usare uno Singleton Pattern.

Se si sta per un'applicazione multithread, è necessario assicurarsi inoltre che gli accessi alle proprietà dell'istanza del singleton siano sicuri.

Come sempre, si prega di riflettere attentamente sull'introduzione di qualsiasi tipo di global nella propria applicazione, ma non aver paura di usarlo. Un sacco di cose sono davvero globali, come App.Settings per esempio senza avere nulla di "cattivo" in esse.

Questo article on MSDN spiega come creare correttamente un singleton in C#.

+2

@ Jorge, con rispetto questo è un cattivo consiglio. Un singleton non dovrebbe essere utilizzato solo per dati statici, i requisiti per il pattern singleton sono in realtà più rari di quanto si pensi, più si limita a limitare l'utilizzo delle risorse e si assicura che le chiamate di metodo stiano invocando uno stato coerente ... non solo trattenendo dati statici . –

+0

Ho scoperto che è vero solo in teoria ma in pratica sono altrettanto utili. Forniscono l'instanstazione pigra, un punto di accesso comune e il livello di astrazione necessario quindi, in pratica, quando si tratta di essere pragmatico, mi ritrovo a utilizzarli comunque. –