¿Cuál es la razón para hacer que ciertos métodos para tipos de datos sean estáticos?

Aug 15 2020

En C#, por ejemplo, hay métodos estáticos para saber si una cadena es nula o vacía , encontrar un elemento en una matriz, borrar una matriz, etc. Sin embargo, hay un método de instancia para reemplazar caracteres en una cadena, y tanto estático como de instancia. Métodos para copiar elementos entre arreglos.

De manera similar, en Python hay funciones para obtener la longitud de una lista, para filtrar una lista, etc., pero también hay métodos de instancia para encontrar el índice de un elemento y para copiar la lista.

Por el contrario, en JavaScript, prácticamente cualquier operación que necesite hacer en un tipo de datos incorporado será accesible a través del método o la propiedad de la instancia.

Entonces, ¿cuál es la razón para hacer que ciertas cosas sean estáticas y otras no?

EDITAR : para ser claros, entiendo el propósito de los métodos estáticos. Mi pregunta es más sobre por qué ciertos métodos se escriben como estáticos cuando podrían haberse escrito como métodos de instancia. Como Findpara arreglos y Formatcadenas en C#, filtery lenen Python.

Respuestas

2 AvnerShahar-Kashtan Aug 15 2020 at 15:09

EDITAR : la pregunta se ha refinado, por lo que refinaré mi respuesta, pero dejaré la anterior a continuación para que los comentarios no sean irrelevantes.

Puede haber varias razones para implementar un método como un método estático en lugar de un método de instancia, con diferentes lenguajes o marcos que posiblemente tengan diferentes fundamentos:

  1. La interfaz pública de un objeto es un contrato. Si su Arraytipo expone un Sortmétodo, cada matriz a partir de ahora, independientemente del tipo o la versión del lenguaje, debe admitirlo. Sin embargo, si an Arrayes solo una representación de datos en la memoria con un contrato delgado y la lógica se mueve a una clase como Array.Sort, le brinda más flexibilidad para ampliar o modificar su comportamiento sin romper la compatibilidad.

  2. Vea esta cita de Clean Code de Bob Martin :

Los objetos exponen el comportamiento y ocultan datos; La estructura de datos expone los datos y no tiene un comportamiento significativo"

En este caso, la Listclase es una clase que expone el comportamiento: oculta sus datos (se implementa como una matriz redimensionable, pero eso es un detalle de implementación), pero expone la funcionalidad. An int[], sin embargo, es una estructura de datos. intEs un bloque asignado secuencialmente . Tiene una Lengthpropiedad porque es parte de sus datos , pero no tiene mucho comportamiento: el comportamiento se descarga a una clase que opera en él.

  1. Podría ser una elección estilística. Python no es un lenguaje puramente OO, y es posible que no tenga la garantía de Java/C# "todo es un objeto", por lo que optó por usar funciones de lenguaje como len()esa, independientemente de si su parámetro es una instancia de objeto o no.

Respuesta anterior

La razón de ser de los métodos estáticos en C# es tener métodos vinculados a un tipo pero no a una instancia . Puede haber varias razones para eso:

  1. Los métodos que pueden operar tanto en una instancia nullcomo en string.IsNullOrEmpty, naturalmente, no pueden ser métodos de instancia, porque es posible que no haya una instancia.
  2. Los métodos de fábrica que crean una instancia, de manera similar, no tienen una instancia desde la cual llamar. Por ejemplo, el método estático alguien obsoleto WebRequest.Create()devuelve una nueva instancia de un tipo derivado de WebRequest.
  3. Si bien es fácil olvidarlo, .NET tiene un manejo diferente para un tipo integral nativo ( int i =5) y un tipo de referencia encuadrado a su alrededor ( object boxed = 5). Si llama a un método en un tipo de valor ( int i = 5; t.ToString();), incurre en el costo de encasillarlo. Es por eso que algunas operaciones no se definen como un método sobre un objeto, sino como un método estático que acepta un valor. Es por eso que las operaciones matemáticas como Math.Absno se definen como métodos en los tipos en caja, sino como funciones estáticas que reciben y devuelven valores.
  4. A veces se utilizan métodos estáticos para "configurar" un tipo, no una instancia específica sino el comportamiento de ese tipo en el sistema. Por ejemplo, [ServicePointManager.SetTcpKeepAlive()][1]configura el comportamiento de todas las clases que usan la pila de HTTP(s) compartido(s) en .NET, para que pueda configurarlas todas a través de estos métodos estáticos.
5 amon Aug 15 2020 at 15:28

Los métodos estáticos tienen mucho sentido

  • cuando el método está relacionado con el tipo pero no requiere una instancia existente; o
  • cuando el lenguaje admite espacios de nombres solo a través de clases.

C# solo admite funciones como miembros de clases, por lo que las funciones auxiliares deben escribirse como métodos estáticos. La clase C# Mathes un excelente ejemplo.

JavaScript no tiene clases, pero cada variable no local está asociada con algún objeto; en el navegador, se puede acceder a la mayoría de las API a través del windowobjeto. Sin embargo, hay métodos a los que se puede acceder a través de un objeto similar a una clase, por ejemplo, Array.isArray(x).

Python tiene un diseño idiosincrásico que está principalmente orientado a objetos, pero tiene algunas funciones integradas como len()o iter(), en gran parte por razones históricas. Bajo el capó, invocan métodos reales, por ejemplo, iter(x)es por lo general x.__iter__(), con un respaldo para objetos que se pueden indexar como una lista.

Más interesantes son los métodos que staticno se deben a las peculiaridades del lenguaje, sino a que tiene sentido. Los métodos similares a constructores o de fábrica son el ejemplo clásico en el que no tenemos un objeto existente al que podamos llamar un método. Algunas funciones tampoco operan exactamente en un objeto, por ejemplo, String.IsNullOrEmpty(x)opera en cero o un objeto. Esto no funciona como un método, por ejemplo x.IsNullOrEmpty(), arrojaría una excepción si es nulo. El Array.isArray(x)método en JS es otro gran ejemplo: queremos llamar isArray(x)a objetos de cualquier tipo, no solo a matrices. Por lo tanto, un método de instancia no funciona a menos que sea parte del prototipo de cada objeto.