Почему C # статически типизирован? - PullRequest
31 голосов
/ 13 мая 2009

Я веб-программист PHP, который пытается изучать C #.

Я хотел бы знать, почему в C # требуется указывать тип данных при создании переменной.

Class classInstance = new Class();

Зачем нам нужно знать тип данных перед экземпляром класса?

Ответы [ 17 ]

106 голосов
/ 13 мая 2009

Как уже говорили другие, C # является статическим / строго типизированным. Но я больше отвечаю на ваш вопрос: «Почему вы хотите, чтобы C # был статическим / строго типизированным, как это? Какие преимущества это имеет по сравнению с динамическими языками?»

Имея это в виду, есть много веских причин:

  • Стабильность Некоторые типы ошибок теперь автоматически обнаруживаются компилятором, прежде чем код когда-либо приблизится к производству.
  • Удобочитаемость / ремонтопригодность Теперь вы предоставляете дополнительную информацию о том, как должен работать код, будущим разработчикам, которые его прочитают. Вы добавляете информацию о том, что определенная переменная предназначена для хранения определенного вида значения, и это помогает программистам понять, какова цель этой переменной.

    Возможно, именно поэтому, например, руководящие принципы Microsoft по стилю рекомендовали программистам VB6 ставить префикс типа с именами переменных, а программисты VB.Net - нет.

  • Производительность Это самая слабая причина, но позднее связывание / утка может быть медленнее. В конце концов, переменная относится к памяти, которая структурирована определенным образом. Без строгих типов программе придется выполнять дополнительную проверку или преобразование типов за кулисами во время выполнения, поскольку вы используете физически структурированную память, как если бы она была логически структурирована другим способом.

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

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

  • Better Dev Tools Если ваша IDE знает, к какому типу относится переменная, она может дать вам дополнительную информацию о том, что может делать эта переменная. Это намного сложнее для IDE, если он должен определить тип для вас. И если вы получите дополнительную помощь по мелочам API из IDE, то вы, как разработчик, сможете разобраться с более крупным и богатым API и быстрее его получить.

Или, может быть, вам просто интересно, почему вы должны указывать имя класса дважды для одной и той же переменной в одной строке? Ответ двоякий:

  1. Часто нет. В C # 3.0 и более поздних версиях вы можете использовать ключевое слово var вместо имени типа во многих случаях. Переменные, созданные таким образом, по-прежнему статически типизированы, но тип теперь выведен для вас компилятором.
  2. Благодаря наследованию и интерфейсам иногда тип с левой стороны не совпадает с типом с правой стороны.
23 голосов
/ 13 мая 2009

Это просто, как язык был разработан. C # является языком в стиле C и следует по образцу типов слева.

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

var variable = new SomeClass();

Но в то же время вы также можете утверждать, что вы все еще объявляете тип на LHS. Только то, что вы хотите, чтобы компилятор выбрал его для вас.

РЕДАКТИРОВАТЬ

Пожалуйста, прочтите это в контексте оригинального вопроса пользователей

зачем нам [имя класса] перед именем переменной?

Я хотел прокомментировать несколько других ответов в этой теме. Многие люди в ответ дают «C # статически». Хотя утверждение верно (C # является статически типизированным), оно почти полностью не связано с вопросом. Статическая типизация не требует, чтобы имя типа находилось слева от имени переменной. Конечно, это может помочь, но это выбор дизайнера языка, а не обязательная особенность языков статической типизации.

Это легко доказать, рассматривая другие статически типизированные языки, такие как F #. Типы в F # появляются справа от имени переменной и очень часто могут быть вообще опущены. Есть также несколько встречных примеров. Например, PowerShell чрезвычайно динамичен и размещает все его типы, если они включены, слева.

21 голосов
/ 13 мая 2009

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

Например, даны следующие типы:

class Foo { }
class Bar : Foo { }
interface IBaz { }
class Baz : IBaz { }

C # позволяет вам сделать это:

Foo f = new Bar();
IBaz b = new Baz();

Да, в большинстве случаев компилятор может определить тип переменной из присваивания (например, с ключевым словом var), но это не так, потому что я показали выше.

Редактировать: В порядке упорядочения - хотя C # строго обозначен , важным отличием (с точки зрения этого обсуждения) является то, что оно на самом деле также статически типизированный язык. Другими словами, компилятор C # выполняет статическую проверку типов во время компиляции.

16 голосов
/ 13 мая 2009

C # является статически типизированным , строго типизированным языком, таким как C или C ++. В этих языках все переменные должны быть объявлены определенного типа.

9 голосов
/ 13 мая 2009

В конечном счете, потому что так сказал Андерс Хейлсберг ...

5 голосов
/ 13 мая 2009

Вам нужно [имя класса] впереди, потому что есть много ситуаций, в которых первый [имя класса] отличается от второго, например:

 IMyCoolInterface obj = new MyInterfaceImplementer();
 MyBaseType obj2 = new MySubTypeOfBaseType();

и т.д.. Вы также можете использовать слово «var», если не хотите явно указывать тип.

3 голосов
/ 12 июля 2009

Зачем нам нужно знать тип данных до экземпляра класса?

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

Рассмотрим следующий фрагмент, отладка которого была бы кошмаром, если вы не получили ошибки до времени выполнения.

 void FunctionCalledVeryUnfrequently()
 {
   ClassA a = new ClassA();
   ClassB b = new ClassB();
   ClassA a2 = new ClassB(); //COMPILER ERROR(thank god)

   //100 lines of code

   DoStuffWithA(a);
   DoStuffWithA(b);      //COMPILER ERROR(thank god)
   DoStuffWithA(a2);
 }

Когда вы думаете, что можете заменить new Class () на число или строку, синтаксис будет иметь гораздо больший смысл. Следующий пример может быть немного многословным, но может помочь понять, почему он спроектирован таким, какой он есть.

   string s = "abc";
   string s2 = new string(new char[]{'a', 'b', 'c'});
   //Does exactly the same thing

   DoStuffWithAString("abc");
   DoStuffWithAString(new string(new char[]{'a', 'b', 'c'}));
   //Does exactly the same thing
2 голосов
/ 13 мая 2009

C #, как отмечали другие, является языком со строгой типизацией.

Заранее указав, какой тип вы собираетесь создать, вы получите предупреждения во время компиляции, когда попытаетесь присвоить недопустимое значение. Заранее указав, какой тип параметров вы принимаете в методах, вы получаете те же предупреждения во время компиляции, когда случайно передаете бессмысленный метод в метод, который его не ожидает. Это снимает накладные расходы на некоторую паранойю от вашего имени.

Наконец, и довольно приятно, что C # (и многие другие языки) не обладают таким же смешным менталитетом «конвертировать что-либо во что угодно, даже если это не имеет смысла», как в PHP, что, откровенно говоря, может вас запутать больше, чем помогает.

1 голос
/ 13 мая 2009

Одна вещь, которая не была упомянута, это то, что C # является CLS (Common Language Specification) совместимым языком. Это набор правил, которых должен придерживаться язык .NET для обеспечения взаимодействия с другими языками .NET.

Так что на самом деле C # просто соблюдает эти правила. Цитировать эту статью MSDN :

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

Если ваш компонент использует только CLS функции в API, которые он предоставляет другой код (в том числе производный классы), компонент гарантирован быть доступным из любого программирования язык, который поддерживает CLS. Компоненты, которые придерживаются CLS правила и использовать только функции включены в CLS, как говорят, CLS-совместимые компоненты

Частью CLS является CTS Система общего типа .

Если для вас недостаточно аббревиатур, то в .NET есть еще тонна, например CLI, ILasm / MSIL, CLR, BCL, FCL,

1 голос
/ 13 мая 2009

В C # 3.0 вы можете использовать ключевое слово 'var' - оно использует статический тип, чтобы определить тип переменной во время компиляции

var foo = new ClassName();

С этого момента переменная 'foo' будет иметь тип 'ClassName'.

...