Другой общий случай, когда можно получить это исключение, включает в себя насмешливые классы во время модульного тестирования. Независимо от используемой насмешливой структуры, вы должны убедиться, что все соответствующие уровни иерархии классов должным образом высмеиваются. В частности, все свойства HttpContext
, на которые ссылается тестируемый код, должны быть изделены.
См. « Исключение NullReferenceException при проверке пользовательского AuthorizationAttribute » для несколько подробного примера.
Простой ответ заключается в том, что ключевое слово struct
присутствует, чтобы ограничить поиск идентификатора tm
только пользовательскими типами классов . Вероятно, он оставлен для совместимости с C, где это необходимо.
Вопреки тому, что говорят другие, нет такой функции, как auto-typedef , и C и C ++ не отличаются в отношении того, как управляются идентификаторы для пользовательских типов. Единственное различие заключается в поиске.
В вашем примере tm может быть типизированной структурой.
, например.
typedef struct tm_t
{
int x;
}tm;
, а затем вы можете сделать
tm t;
Пользовательские типы имеют собственное пространство идентификаторов, то есть когда компилятор разбирает файл, он сохраняет каждый идентификатор в соответствующем пространстве.
Когда вы ссылаетесь на tm
, компилятор C (как C ++) будет искать этот идентификатор в пространстве глобального идентификатора. Затем компилятор C ++ будет искать в пользовательском пространстве идентификаторов типов, если ранее не нашел символ.
В принципе, если вы хотите иметь такое же поведение, как на C ++, добавьте эту строку:
typedef struct tm tm;
Вы можете объединить объявление структуры и typedef следующим образом:
typedef struct tm { int field } tm;
Или используя анонимную структуру:
typedef struct { int field } tm;
То же поведение применяется для enum
и union
:
typedef enum { VALUE } myEnum;
typedef union { int integer; char charArray[4]; } myUnion;
Использование struct tm t;
для совместимости с C, в котором объявление структуры с именем «tm
» определяет тип с именем «struct tm
», но не с именем «tm
» (в отличие от C ++, в котором оба имени для типа объявлены).
В C имена тегов структуры не образуют идентификаторы в глобальном пространстве имен
struct not_a_global_identifier { /* ... */ };
. Чтобы ссылаться на эту структуру, вы должны использовать ключевое слово struct
(чтобы указать пространство имен)
struct not_a_global_identifer object;
или создать новый идентификатор в глобальном пространстве имен с помощью typedef
typedef struct not_a_global_identifer { /* ... */ } global_name_space_identifier;
В C имеется 4 пространства имен, см. 6.2.3 в C99 Standard :
Это законная программа C: -)
int main(void) {
typedef struct foobar { int foobar; } foobar;
foobar boo;
boo.foobar = 42;
if (boo.foobar) goto foobar;
foobar:
return 0;
}
Вы можете увидеть ссылку, приведенную ниже, и цитату оттуда. «В C вы должны явно использовать ключевое слово struct для объявления структуры. В C ++ это необязательно после определения типа». См. Ссылку для получения дополнительной информации и примеров.
http://msdn.microsoft.com/en-us/library/64973255%28v=vs.80%29.aspx