2009-02-27 15 views
6

Para una aplicación que estoy escribiendo, quiero tener extensibilidad extrema y los métodos de extensión parecen darme lo que quiero, además de la capacidad de llamarlos sin una instancia, que también necesito.Métodos estáticos vs métodos de instancia en C#

Recuerdo haber leído que los métodos estáticos son más rápidos que los métodos de instancia pero no obtienen las ventajas de GC. ¿Es esto correcto?

Es muy poco probable que cambie mi diseño a menos que encuentre una alternativa superior por diseño, no velocidad. Pero aún así para obtener información adicional, quiero saber las diferencias en velocidad, GC, etc.

EDIT: Gracias. Más información: Digamos que tenemos una clase Persona:

class Person 

que puede tener un método de instancia Distancia tan parecida:

this.Distance (Person p) 

Esto es grande, pero esto no me da la capacidad de calcular la distancia entre 2 puntos (digamos Point3), sin crear instancias de la clase Person.

Lo que quiero hacer es esto:

class Person (no Distance methods) 

pero de extensión métodos de Distancia:

Distance (this Person, Person) 
Distance (this Point3, Point3) 

De esta manera puedo hacer las dos cosas:

myPerson.Distance (yourPerson) 

y

Extensions.Distance (pointA, pointB) 

EDIT2: @Jon, sí, creo que eso era lo que quería decir (no obtener las ventajas de GC), pero de alguna manera pensé que los métodos estáticos crean esta carga/sobrecarga.

Respuesta

13

¿Qué quiere decir con "no obtener las ventajas de GC"? Los métodos no son basura recolectada, los casos sí.

Los métodos virtuales son ligeramente más lentos que los no virtuales, y supongo que existe esa molesta comprobación nula antes de cualquier método de instancia, pero no es significativo. Ve con el diseño más apropiado.

métodos estáticos son un dolor para la prueba, aunque - por ejemplo, si se autentica en el método Foo() llamando a un método estático, a continuación, cuando se está probando Foo() no se puede hacer simplemente llamar a un simulacro de autenticador (a menos que la estática método mismo le permite hacer eso). Sin embargo, si le da la instancia original de lo que está probando a una implementación simulada de alguna interfaz que contiene un método Authenticate(), puede hacer que se comporte como lo desee.

EDITAR: En este caso, parece que lo que realmente necesita es un método de instancia en su tipo Point para calcular la distancia entre dos puntos ("este" y otro) - o potencialmente un método de fábrica estático en el Distance tipo.

+0

Gracias Jon. ¿Tiene sentido ahora? –

+0

Gracias Jon. No tengo el tipo de distancia porque es solo un flotador. Lo de la instancia es donde no estoy seguro de si debo usar. Al igual que puedo tener el método Distance en Point, pero también quiero decir PointToRGBColor, pero en mi diseño para mí parece que este método RGB también debería ser una extensión. –

+0

Ahora la creación de una instancia aquí tiene 100% de sentido, como el método RGB podría estar en la clase Color. Pero esto me impide hacer un uso directo de la funcionalidad si debe haber una instancia. Para Point, está bien porque es el tipo más básico que uno necesita para usarlo. –

13

Elegir entre métodos estáticos y de instancia es una cuestión de diseño orientado a objetos. Si el método que está escribiendo es comportamiento de un objeto, entonces debe ser un método de instancia. Si no depende de una instancia de un objeto, debe ser estático.

Básicamente, los métodos estáticos pertenecen a un tipo, mientras que los métodos de instancia pertenecen a las instancias de un tipo.

+0

¿Significa que para un objeto Cliente, tener un método de instancia como "GetAge()" y un método estático como "CustomerHelper.GetCustomersFromState (int stateId)" es la forma correcta de hacerlo? – Shyju

+0

'GetAge' tiene sentido como método de instancia. Sin embargo, no tengo claro el último. –

+0

@MehrdadAfshari Entonces 'CustomerDAL' _class_ que tiene un _method_' GetAllCustomers (..) '.... lo mismo que' EmployeeDAL' que tiene 'GetAllEmployees()' ..... ¿deberían ser métodos de instancia? y si es así, ¿qué tipo de método (por favor, indique el ejemplo) debe ser estático en esas clases? –

5

Si al ser más rápido quiere decir que el código dentro del método se ejecuta más rápido, entonces no. Un código en un método estático es tan rápido como el código en un método no estático.

Si está hablando de la sobrecarga de realizar la llamada al método, se vuelve un poco más complejo. Es común para lenguajes como Java que las llamadas a instancias tengan más sobrecarga. Sin embargo, en C# este no es el caso porque los métodos de instancia no son virtuales por defecto.

Por lo tanto, un método virtual tiene un poco más de gastos generales que un método no virtual. Los métodos estáticos no pueden ser virtuales, pero los métodos de instancia pueden declararse virtuales.

En cuanto a la recolección de basura, esto es principalmente relevante para los campos, no para los métodos. Se puede acceder a los campos estáticos desde cualquier lugar del código, de modo que el recolector de elementos no utilizados no pueda determinar si la referencia se usará nuevamente, por lo que nunca se recopilará.

2

Basado en su ejemplo, me gustaría escribir una función de utilidad estática para encontrar la distancia entre dos puntos:

public static class Geometry 
{ 
    public static double GetDistanceBetween(Point a, Point b) { ... } 
} 

Y entonces yo le daría a la persona una propiedad llamada Posición que regresó un punto. Entonces podría escribir:

double distance = Geometry.GetDistanceBetween(personA.Position, personB.Position); 

Ya está prácticamente en inglés, ¿por qué hacerlo más oscuro? Si realiza Distancia un método, entonces se puede escribir:

personA.Distance(personB) 

o:

personB.Distance(personA) 

No hay diferencia entre estos dos ordenamientos, y sin embargo, el uso de la sintaxis del método de guardia sugiere que podría haber una diferencia.

+0

Gracias, sí Posición es una propiedad en mi clase de Persona. Pero estas operaciones las construye el usuario a través de un gráfico esquemático.Así que quería tener una forma unificada de hacerlo, pero también tener la capacidad de usarlos directamente sin crear elementos esquemáticos en la interfaz de usuario. –

+0

Por cierto, no obtuve la segunda parte. Te refieres a la persona. Distancia (persona B) y Extensiones. ¿La distancia es la misma? –

+0

Primero pido a la persona A que calcule la distancia a la persona B, luego le pido a la persona B que calcule la distancia a la persona A. Las dos personas son intercambiadas. Al convertirlo en un método, implica que la persona lo está descifrando por su propia cuenta, lo que es engañoso. Estoy recomendando no agregar un método de distancia –

Cuestiones relacionadas