2009-05-21 25 views
8

Estoy acostumbrado a los lenguajes de scripting. PHP, Javascript etc. y he escrito algunas aplicaciones Java y C# relativamente simples. Esta es una pregunta en la que repetidamente he necesitado una respuesta, y me imagino que no soy la única.¿Cómo persisto datos sin variables globales?

Digamos que estoy en Javascript.

Tengo la función A(), llamada por la GUI, que recupera algún valor.

La función B(), también llamada por la GUI, requiere ese valor, pero la función B() se llamará un número arbitrario de veces, un período de tiempo arbitrario después de A().

No quiero que A() recalcule el valor cada vez.

Un ejemplo son las credenciales de inicio de sesión. A() solicita un nombre de usuario y B() usa ese valor para anexarlo a un registro cada vez que se invoca.

Para esto, probablemente solo use una variable global.

Ahora, C#. ¡Sin variables globales! ¿Cómo se supone que haga esto?

Editar: goza de las respuestas, pero hay un montón de "Tratar de no usar variables globales", comenta. Lo que sí entiendo, pero me gustaría escuchar los patrones alternativos para este requisito.

+2

Puede considerar leer en "memoization", que es el nombre para la técnica general de recordar cuál era el resultado de una función y volver a utilizarla más tarde sin volver a calcularla. Hay muchas técnicas interesantes para la memorización eficiente. –

Respuesta

4

En primer lugar, siempre pregúntese si realmente necesita tener un sistema global, a menudo no lo hará. Pero si realmente tiene que tener uno ...

La mejor manera de hacer esto es tener una propiedad estática en alguna clase sensiblemente llamado, en la práctica se convierte en su variable global

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

//...somewhere in your code 

Credentials.Username = "MyUserName"; 

EDIT:

Un par de personas aquí han dicho que las Variables Globales son malas, y estoy de acuerdo con este sentimiento, y parece que los diseñadores de C# también están de acuerdo ya que simplemente no están disponibles.

Sin embargo, debemos ver las razones por las cuales los Globals son malos, y en su mayoría son considerados como malos porque rompe las reglas de encapsulación. Sin embargo, los datos estáticos no son necesariamente malos, lo bueno de los datos estáticos es que puedes encapsularlos, mi ejemplo anterior es un ejemplo muy simplista de eso, probablemente en un escenario del mundo real incluirías tus datos estáticos en la misma clase que otro trabajo con las credenciales, tal vez una clase de inicio de sesión o una clase de usuario o lo que tenga sentido para su aplicación.

+0

Yo enfatizaría fuertemente: NO uses globales :) Sin embargo, si insistes, esta es una buena manera de hacerlo. –

+0

@Marcel: C# no tiene valores globales. – Brian

+0

Gracias por la respuesta Tim. Marcel: para este requisito, ¿qué sugieres que haga en su lugar? – ChristianLinnell

0

En C#, una de las maneras de obtener un comportamiento similar a las variables globales es utilizar métodos de clase estáticos y variables de clase. Los métodos y las variables de la clase estática tienen una única instancia en C# y se asemejan a las variables globales en otros idiomas.

Dicho esto, para su problema, suena más como un problema de diseño. C# está muy enfocado en el Diseño Orientado a Objetos; Sospecho que por el problema que has dado, un mejor OOD resolvería tu problema.

5

Esto no es una buena práctica, pero si realmente lo necesita, hay un número de maneras:

  1. aplicaciones Web: Usted puede poner su variable en algún tipo de contexto, como la sesión o el alcance de la aplicación.
  2. Aplicaciones de escritorio: puede crear un objeto y almacenarlo como una propiedad de una clase que siempre tiene un objeto activo.
  3. Cualquier tipo de aplicación: use una propiedad pública estática. Es visible para todos.
+0

Gracias por la respuesta ... entonces, ¿qué buenas prácticas sugerirías? – ChristianLinnell

+0

¡Cambie su diseño para alinearlo mejor con el paradigma de diseño del idioma que ha elegido! – tomfanning

0

La función A sería parte de una clase (llámala C). La función A podría almacenar las credenciales de inicio de sesión y proporcionar una función (o en C#, una propiedad) para obtener las credenciales. Cuando se requieren, puede simplemente usar la propiedad para obtener las credenciales almacenadas y pasarlas a la Función B (en una clase diferente).

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

Yo diría que probablemente deba usar un Singleton Pattern.

Si va a una aplicación de subprocesos múltiples, también debe asegurarse de que los accesos a las propiedades de la instancia del singleton sean seguros para la ejecución de los hilos.

Como siempre, piense detenidamente sobre la introducción de cualquier tipo de global en su aplicación, pero no dude en usarlo. De hecho, muchas cosas son globales, como la Configuración de la aplicación, por ejemplo, sin tener nada "malo" en ellas.

Este article on MSDN explica cómo crear correctamente un singleton en C#.

+2

@Jorge, con respeto este es un mal consejo. Un singleton no debe usarse solo para datos estáticos, los requisitos para el patrón singleton son más raros de lo que la gente piensa, se trata más de limitar el uso de recursos y asegurarse de que las llamadas a métodos invoquen un estado consistente ... no solo aferrándose a datos estáticos . –

+0

Descubrí que es cierto solo en teoría, pero en la práctica son igual de útiles. Proporcionan instanstia perezosa, un punto de acceso común y el nivel de abstracción necesario, así que, básicamente, cuando se trata de ser pragmático, de todos modos, me encuentro utilizándolos. –