La palabra clave static
puede ser un poco difícil de entender para los novatos. Su propósito principal es identificar a un miembro de la clase como no perteneciente a ninguna instancia única de la clase, sino a la clase en sí.
Sin entrar en demasiados detalles, C # (y Java) aplican rígidamente el ideal orientado a objetos de que todo el código y los datos deben pertenecer a un objeto y, por lo tanto, tienen un alcance, visibilidad y vida útil limitados. En general, es la mejor práctica dondequiera que se aplique el principio fundamental de un objeto que representa algo del mundo real. Sin embargo, no siempre; a veces, lo que necesita es una función o variable a la que puede acceder desde en cualquier lugar en el código, sin que tenga que pasar una referencia a un objeto que lo contiene, y con la garantía de que los datos que busca En o cambiar es exactamente de lo que todos los demás están tratando, y no una copia que pertenezca a una instancia diferente de un objeto.
Tal comportamiento estaba disponible en C y C ++ en la forma de la función o variable "global", que no estaba encapsulada en un objeto. Entonces, como compromiso, C # y Java admiten el "alcance estático", un punto intermedio entre el código verdaderamente global sin objeto primario y miembros de instancia de alcance limitado.
Cualquier "miembro de código" (función, propiedad, campo) declarado como static
entra en el alcance desde la primera línea de la función main()
del programa, y no lo deja hasta que la función main()
termine. En un lenguaje sencillo, existe un miembro estático y se puede usar mientras el programa se esté ejecutando. Además, los miembros estáticos se invocan llamándolos como miembros del tipo en sí, no como miembros de ninguna instancia de ese tipo:
public class Foo
{
public int MyInt {get;set;} //this is an "instance member"
public static int MyStaticInt {get;set;} //this is a "static member"
}
...
var myFoo = new Foo();
myFoo.MyInt = 5; //valid
myFoo.MyStaticInt = 5; //invalid; MyStaticInt doesn't belong to any one Foo
Foo.MyInt = 5; //invalid; MyInt only has meaning in the context of an instance
Foo.MyStaticInt = 2; //valid
Esto hace que los miembros estáticos sean visibles para cualquier código que tenga conocimiento del tipo, ya sea que conozcan o no una instancia única de él.
Para responder a su pregunta, el beneficio principal de marcar algo como estático es que se hace visible donde se conoce el tipo, independientemente de si el código consumidor tiene o puede obtener una instancia del objeto que lo contiene. También hay un beneficio de rendimiento ligero ; Debido a que el método está en el alcance estático, solo puede acceder a otros miembros estáticos (de la misma clase u otros), y lo que se pasa como parámetro. Por lo tanto, el tiempo de ejecución no tiene que resolver ninguna referencia a la instancia actual del objeto contenedor, ya que normalmente tendría que hacerlo con un método de instancia para proporcionar información de estado específica del contexto.
Las clases enteras también se pueden marcar como estáticas; Al hacerlo, le dice al compilador que la declaración de clase constará únicamente de miembros estáticos y, por lo tanto, no se puede crear una instancia. Esta es una manera fácil de asegurar que haya una, y solo una, copia de un objeto en la memoria; hacer la clase y todo en ella estática. Sin embargo, es muy raro que esta sea la mejor solución para tal necesidad. En una situación donde se requiere exactamente una copia de un conjunto de datos, el "singleton" se recomienda en su lugar; esta es una clase no estática, que utiliza un descriptor de acceso estático y un constructor no público para proporcionar acceso a una sola instancia de sí misma. Teóricamente, un singleton proporciona los mismos beneficios que una clase completamente estática, pero con la capacidad adicional de usar la clase de forma orientada a objetos basada en instancias.