2009-02-27 11 views
6

Для приложения, которое я пишу, я хочу иметь экстремальные методы расширяемости и расширения, кажется, дает мне то, что я хочу, плюс возможность называть их без экземпляра, который мне тоже нужен.Статические методы vs методы экземпляра в C#

Помню, что статические методы быстрее, чем методы экземпляров, но не имеют преимуществ GC. Это верно?

Очень маловероятно, что я изменю свой дизайн, если не найду превосходную альтернативу по дизайну, а не по скорости. Но все же для дополнительной информации я хочу знать различия в скорости, GC и т. Д.

EDIT: Спасибо. Более подробную информацию: Допустим, у нас есть класс Person:

class Person 

, который может иметь метод экземпляра Distance так как:

this.Distance (Person p) 

Это замечательно, но это не дает мне возможность рассчитать расстояние между 2 точками (например, Point3), без создания экземпляров класса Person.

То, что я хочу сделать это:

class Person (no Distance methods) 

но удлинительные методы Расстояние:

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

Таким образом, я могу как сделать:

myPerson.Distance (yourPerson) 

и

Extensions.Distance (pointA, pointB) 

EDIT2: @Jon, да, я думаю, это было то, что подразумевалось под (не получить преимущества GC), но я почему-то думал, что статические методы создают это бремя/накладные расходы.

ответ

13

Что вы подразумеваете под «не получают преимущества GC»? Методы - это не сбор мусора - экземпляры.

Виртуальные методы: немного медленнее, чем не виртуальные, и я думаю, что это надоедливая проверка нуля перед любым методом экземпляра, но это не существенно. Идите с наиболее подходящей конструкцией.

Статические методы являются боль для тестирования, хотя - например, если вы аутентификации в методе Foo(), вызвав некоторый статический метод, а затем, когда вы тестируете Foo() вы не можете сделать это просто позвонить макет аутентификатор (если статическая сам метод позволяет это сделать). Однако, если вы даете исходный экземпляр того, что вы тестируете макетной реализации какого-либо интерфейса, содержащего метод Authenticate(), вы можете заставить его вести себя, как хотите.

EDIT: В этом случае вам кажется, что вам действительно нужен метод экземпляра для вашего типа Point, чтобы рассчитать расстояние между двумя точками («это» одно и другое) или потенциально статический заводский метод на Distance тип.

+0

Спасибо Jon. Это имеет смысл сейчас? –

+0

Спасибо, Джон. У меня нет типа расстояния, потому что это просто поплавок. Дело в том, где я не уверен, использовать ли. Как и у меня есть метод Distance в Point, но я также хочу сказать PointToRGBColor, но в моем дизайне мне кажется, что этот метод RGB также должен быть расширением. –

+0

Теперь создание здесь составляет 100%, как метод RGB может быть в классе Color. Но это мешает мне делать прямое использование функциональности, если должен быть экземпляр. Для Point это нормально, потому что это самый базовый тип, который нужно использовать для его использования. –

13

Выбор между статическими и экземплярами - это вопрос объектно-ориентированного дизайна. Если метод, который вы пишете, представляет собой поведение объекта, то это должен быть метод экземпляра. Если он не зависит от экземпляра объекта, он должен быть статическим.

В основном, статические методы относятся к типу, тогда как методы экземпляра относятся к экземплярам типа.

+0

Означает ли это, что для объекта Customer, имеющего метод экземпляра типа «GetAge()» и статический метод, подобный «CustomerHelper.GetCustomersFromState (int stateId)», является правильным способом? – Shyju

+0

'GetAge' имеет смысл как метод экземпляра. Однако я не понимаю последнего. –

+0

@MehrdadAfshari Итак, 'CustomerDAL' _class_, который имеет _method_' GetAllCustomers (..) '.... то же, что и' EmployeeDAL', который имеет 'GetAllEmployees()' ..... должен быть методом экземпляра? и если да - какой метод (пожалуйста, укажите пример) должен быть статичным в этих классах? –

5

Если, будучи быстрее, вы имеете в виду, что код внутри метода выполняется быстрее, а затем нет. Код в статическом методе так же быстро, как и код в статическом методе.

Если вы говорите о накладных расходах на выполнение вызова метода, он становится немного более сложным. Это общепринято для языков, поскольку Java, вызываемый экземплярами, имеет больше накладных расходов. В C# это не так, потому что методы экземпляра по умолчанию не являются виртуальными.

Таким образом, виртуальный метод имеет немного больше накладных расходов, чем не виртуальный метод. Статические методы не могут быть виртуальными, но методы экземпляров могут быть объявлены виртуальными.

Что касается сбора мусора, это в основном касается полей, а не методов. Статические поля могут быть доступны из любой точки кода, поэтому сборщик мусора не может определить, будет ли ссылка использоваться снова, поэтому она никогда не собирается.

2

Основываясь на вашем примере, я хотел бы написать статическую функцию полезности для нахождения расстояния между двумя точками:

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

И тогда я дал бы человеку свойство позиции, которая возвращала точку. Поэтому я мог бы написать:

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

Это уже на английском языке - зачем делать его более неясным? Если вы Distance метод, то вы можете написать:

personA.Distance(personB) 

или:

personB.Distance(personA) 

Там нет никакой разницы между этими двумя порядками, и все же использование синтаксиса метода вызова предполагает, что может быть разница.

+0

Спасибо, да. Позиция - это свойство в моем классе Person. Но эти операции строятся пользователем через схематический график.Поэтому я хотел иметь единый способ сделать это, но также иметь возможность использовать их напрямую, не создавая никаких элементов схемы в пользовательском интерфейсе. –

+0

Btw Я не получил вторую часть. Вы имеете в виду personA.Distance (personB) и Extensions.Distance то же самое? –

+0

Сначала я прошу personA разобраться в расстоянии до человекаB, затем я прошу personB выработать расстояние до человека. Двое людей меняются местами. Сделав это методом, вы подразумеваете, что человек понимает это в своем собственном уникальном, что вводит в заблуждение. Я рекомендую не добавлять метод Distance –

Смежные вопросы