У меня есть некоторый опыт разработки с Java, Javascript и PHP.
Я читаю Microsoft Visual C # 2010 «Step by Step», и я считаю, что это очень хорошая книга о том, как познакомить вас с языком C #.
Кажется, у меня проблемы с пониманием статического ключевого слова. Из того, что я понимаю, если класс объявлен как статический, все методы и переменные должны быть статическими. Метод main всегда является статическим методом, поэтому в классе, в котором существует метод main, все переменные и методы объявляются статическими, если их необходимо вызывать в методе main. Также я заметил, что для вызова статического метода из другого класса вам не нужно создавать объект, для которого вы можете использовать имя класса.
Но какова реальная цель статического ключевого слова? Когда я должен объявить статическую переменную и методы?
источник
Ответы:
Ключевое слово static в C # относится к чему-то в классе или к самому классу, которое является общим для всех экземпляров класса. Например, поле, помеченное как статическое, может быть доступно из всех экземпляров этого класса через имя класса.
Я могу честно сказать, что я никогда не использовал класс, помеченный как статический, за исключением создания методов расширения ( Краткое руководство по методам расширения ).
В любом случае, существует специальные шаблоны проектирования для использования статических методов, такие как фабричная модель и одноплодной шаблон , но важно помнить, что статические методы и конструкторы не имеет дела с каким - либо конкретным экземпляром класса (если вы не разъехаться в), как правило, для расчетов или сравнения объектов. Метод «Main», на который вы ссылаетесь, всегда статичен, но чтобы увидеть его с другой точки зрения, обратитесь к этой статье .
Чтобы продолжить это, вот как вызывается разница между статическими и экземплярами методов, полей и свойств.
Кроме того, проверьте этот пост для более глубокого изучения статических классов.
источник
Вот способ объяснения Джошуа Блоха, который я нахожу блестящим, как большинство из того, что он говорит (да, я фанат Джошуа Блоха :)). Это цитата из памяти.
Представьте, что класс - это план проекта дома. Представьте себе, что дом находится на стадии разработки, так как экземпляр класса предназначен для класса. Из него можно создать один класс (предварительный рисунок) и несколько экземпляров (домов).
Теперь здравый смысл подсказывает, что большинство функций / поведений, которые дом (экземпляр) может иметь / выполнять, даже если они объявлены в чертеже, не могут использоваться, пока фактический дом (экземпляр) не будет сделан из этого синего цвета. -принт (класс). Например, ваш план может содержать в себе место, где должны включаться свет и лампочки, но вы не можете заставить их работать над планом, вы должны построить дом, чтобы иметь возможность включить и выключить свет и включать и выключать определенные лампочки.
Тем не менее, у вас может быть некоторое поведение, которое применимо к черновому варианту напрямую, и которое вы можете использовать / использовать непосредственно в черновом наборе, не создавая фактического дома из этого чертежа. Представьте, что у вашего чертежа есть кнопка, которая после нажатия будет отображать площадь дома, содержащуюся в этом чертеже (вычисляя все длины стен и тому подобное). Очевидно, что вы МОЖЕТЕ сначала построить дом, а затем приступить к измерению его площади, но вы можете сделать это только с одним черновиком, так что было бы более полезно, чтобы это поведение было реализовано в черновике. Такая встроенная кнопка с черным шрифтом, которая вычисляет площадь дома, является эквивалентом наличия статической функции в классе.
источник
Blueprint
класс, который реализует функциональность проекта, в том числе возможность рассчитать площадь дома, выраженную в проекте. Этот экземпляр проекта затем передаетсяBuilder
(в свою очередь, скорее всего, экземпляру), который, в свою очередь, делает все необходимое для создания и вывода потенциально произвольного числаBuilding
экземпляров на основе проекта.Глядя на это таким образом, мне помогает:
Что касается того, когда использовать ключевое слово static:
источник
"Looking at it this way helps"
он. Вы находите это странным, потому что это не совсем верно, но вы можете думать об этом так, если хотите. Вы знаете модель Бора? Это набор правил и идей о том, как атомы и электроны взаимодействуют друг с другом. Модель работает в зависимости от того, что вы делаете, но это не реальность.static
даже если он не использует локальные свойства. Создание вещейstatic
может добавить связь с клиентами, потому что они должны обращаться к классу напрямую. Например, это может усложнить юнит-тестирование с макетом.Простейшее объяснение --- Статический => В каждой среде будет существовать только одна копия.
Таким образом, внутри ВМ или CLR всегда будет только одна копия статического класса, и любой другой класс, ссылающийся на него, должен будет делиться своими методами и данными со всеми другими классами, ссылающимися на него.
Для статической переменной в среде времени выполнения будет только один экземпляр этой переменной, независимо от того, сколько копий класса-владельца создано, когда они ссылаются на статическую переменную, все они будут ссылаться на один и тот же фрагмент памяти.
источник
Статические члены связаны с классом, а не с каким-либо экземпляром этого класса.
Поскольку мы говорим о .Net, рассмотрим класс String , в частности методы Split и Join .
Сплит является методом экземпляра . Создайте строковую переменную, присвойте ей значение, и вы можете вызвать Split () для этой переменной / значения и получить массив «битов»:
Так, например, методы, значение в данном экземпляре класса имеет значение .
Присоединение - это статический метод. Хорошо, это дает Струнный результат , когда данный разделитель и массив строк , чтобы жевать, так что это «что - то делать с» класса струнных, но это не связано с какой - либо конкретной величины в любом случае String ( на самом деле, значения экземпляра являются недоступно для статических методов).
В других языках метод Join мог «застрять» в классе Array (или, возможно, лучше в классе StringArray), но наши друзья в Редмонде решили, что он более «актуален» для класса String, поэтому они поместили его туда ,
Другой альтернативой может быть использование метода Join экземпляра , в котором значение, содержащееся в String [экземпляр класса], которое мы использовали в качестве разделителя присоединения, что-то вроде:
источник
static
Ключевое слово может быть немного трудно для новичков , чтобы понять. Его основная цель состоит в том, чтобы идентифицировать члена класса как принадлежащего не к какому-либо одному экземпляру класса, а вместо этого к самому классу.Не вдаваясь в подробности, C # (и Java) жестко реализуют объектно-ориентированный идеал, согласно которому весь код и данные должны принадлежать объекту, и, следовательно, ограничены по объему, видимости и времени жизни. Это, как правило, лучшая практика, когда применяется фундаментальный принцип объекта, представляющего какую-то реальную вещь. Однако, это не всегда; иногда вам нужна функция или переменная, к которой вы можете получить доступ из любого места в коде, без необходимости передавать ссылку на объект, содержащий ее, и с гарантией того, что данные, которые вы просматриваете или изменяете, - это то , что все иначе имеет дело, а не копия этого, принадлежащая другому экземпляру объекта.
Такое поведение было доступно в C и C ++ в форме «глобальной» функции или переменной, которая не была инкапсулирована в объекте. Таким образом, в качестве компромисса C # и Java поддерживают «статическую область видимости», промежуточную точку между действительно глобальным кодом без родительского объекта и членами экземпляра с ограниченной областью действия.
Любой «элемент кода» (функция, свойство, поле), объявленный как,
static
входит в область действия с первой строки функции программыmain()
и не покидает ее, покаmain()
функция не завершится. Говоря простым языком, статический член существует и может использоваться, пока работает программа. Кроме того, статические члены вызываются путем вызова их как членов самого типа, а не членов какого-либо одного экземпляра этого типа:Это делает статические члены видимыми для любого кода, который знает тип, независимо от того, знают ли они о каком-либо его экземпляре.
Чтобы ответить на ваш вопрос, основное преимущество маркировки чего-либо как статического состоит в том, что оно становится видимым везде, где известен сам тип, независимо от того, имеет ли потребительский код или может получить экземпляр содержащего его объекта. Есть также небольшое преимущество в производительности; Поскольку метод находится в статической области видимости, он может получить доступ только к другим статическим элементам (того же класса или других) и ко всему, что передается в качестве параметра. Следовательно, среда выполнения не должна разрешать какую-либо ссылку на текущий экземпляр содержащего объекта, как это обычно должно быть для метода экземпляра, чтобы предоставлять информацию о состоянии, зависящую от контекста.
Целые классы также могут быть помечены как статические; тем самым вы сообщаете компилятору, что объявление класса будет состоять исключительно из статических членов и, следовательно, не может быть создано. Это простой способ убедиться, что в памяти есть одна и только одна копия объекта; сделать класс и все в нем статичным. Однако очень редко это лучшее решение для такой необходимости. В ситуации, когда требуется ровно одна копия набора данных, вместо этого обычно выступает «синглтон»; это нестатический класс, который использует статический метод доступа и непубличный конструктор, чтобы обеспечить доступ к одному его экземпляру. Теоретически, синглтон обеспечивает почти те же преимущества полностью статического класса, но с добавленной возможностью использовать этот класс объектно-ориентированным способом.
источник