La static
palabra clave 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 una sola instancia de la clase, sino a la clase misma.
Sin entrar en demasiados detalles, C # (y Java) imponen 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, su alcance, visibilidad y vida útil son limitados. En general, esa es la mejor práctica donde se aplica el principio fundamental de un objeto que representa algo del mundo real. Sin embargo, no siempre es así; a veces lo que necesita es una función o variable a la que pueda acceder desde cualquier parte del código, sin requerir que pase una referencia a un objeto que lo contiene, y con la garantía de que los datos que está viendo o cambiando es exactamente lo que todos más está tratando, y no una copia del mismo que pertenece 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. Por lo tanto, como compromiso, C # y Java admiten "alcance estático", un punto intermedio entre el código verdaderamente global sin objeto principal y los miembros de instancia de alcance limitado.
Cualquier "miembro de código" (función, propiedad, campo) declarado como static
entra en el alcance a partir de la primera línea de la main()
función del programa , y no lo abandona hasta main()
que finaliza la función. En inglés simple, 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 alguna instancia del mismo.
Para responder a su pregunta, el beneficio principal de marcar algo como estático es que se hace visible donde se conoce el tipo en sí, independientemente de si el código consumidor tiene o puede obtener una instancia del objeto que lo contiene. También hay un ligero beneficio de rendimiento; Debido a que el método tiene un alcance estático, solo puede acceder a otros miembros estáticos (de la misma clase u otros), y todo lo que se pase 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 consistirá únicamente en miembros estáticos y, por lo tanto, no se puede crear una instancia. Esta es una manera fácil de garantizar que haya una, y solo una, copia de un objeto en la memoria; hacer que la clase y todo lo que contiene sea 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" generalmente 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í mismo. Teóricamente, un singleton proporciona los mismos beneficios que una clase completamente estática, pero con la capacidad adicional de usar la clase de una manera orientada a objetos y basada en instancias.