Я просмотрел все сообщения на reflection, но не смог найти ответ на мой вопрос.
Каковы были проблемы в мире программирования перед .NET-анализом пришел и как он решил эти проблемы?
Пожалуйста, объясните пример.
Я просмотрел все сообщения на reflection, но не смог найти ответ на мой вопрос.
Каковы были проблемы в мире программирования перед .NET-анализом пришел и как он решил эти проблемы?
Пожалуйста, объясните пример.
Следует отметить, что отражение .NET не является революционным - концепции существуют в других рамках.
Отражение в .NET имеет 2 грани:
Информация о типе исследования
Без какого-либо API-интерфейса для отражения/интроспекции становится очень сложно выполнять такие вещи, как сериализация. Вместо того, чтобы это предоставлялось во время выполнения (путем проверки свойств/полей/etc), вам часто требуется генерация кода, то есть код, который явно знает, как сериализовать каждый из ваших типов. Занудный и болезненный, если вы хотите сериализовать то, что не имеет близнеца.
Аналогичным образом, хранить метаданные о свойствах и т.д. некуда, поэтому у вас будет много дополнительного кода или внешних файлов конфигурации. Что-то простое, как возможность сопоставить дружественное имя с свойством (через атрибут) - огромная победа для кода пользовательского интерфейса.
Метапрограммирование
.NET reflection также предоставляет механизм для создания типов (и т.д.) во время выполнения, что чрезвычайно эффективно для некоторых конкретных сценариев; альтернативы:
Я думаю, что для понимания необходимости отражения в .NET нам нужно вернуться к .NET. В конце концов, современные языки, такие как Java и С#, не имеют BF истории (перед отражением).
С++, возможно, оказал наибольшее влияние на С# и Java. Но у С++ изначально не было отражения, и мы закодировали без него, и нам удалось пройти. Иногда у нас был указатель void, и он использовал бы бросок, чтобы заставить его в любой тип, который мы хотели. Проблема здесь заключалась в том, что бросок может потерпеть неудачу с ужасными последствиями:
double CalculateSize(void* rectangle) {
return ((Rect*)rectangle)->getWidth() * ((Rect*)rectangle)->getHeight());
}
Теперь есть много аргументов, почему вы не должны были кодировать себя в эту проблему в первую очередь. Но проблема не сильно отличается от .NET 1.1 с С#, когда у нас не было дженериков:
Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
return ((Rect)shape).Width * ((Rect)shape).Height;
}
Однако, когда пример С# не работает, он делает это с исключением, а не с потенциальным ядром ядра.
Когда отражение было добавлено в С++ (известное как идентификация типа времени выполнения или RTTI), это было горячо обсуждено. В книге Страуступа "Дизайн и эволюция C++" он перечисляет следующие аргументы против RTTI, в том, что некоторые люди:
Declared the support unnecessary Declared the new style inherently evil ("against the spirit of C++") Deemed it too expensive Thought it too complicated and confusing Saw it as the beginning of an avalanche of new features
Но это позволило нам запросить тип объектов или объекты объектов. Например (используя С#)
Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
if(shape is Rect) {
return ((Rect)shape).Width * ((Rect)shape).Height;
}
else if(shape is Circle) {
return Math.Power(((Circle)shape).Radius, 2.0) * Math.PI;
}
}
Конечно, при правильном планировании этот пример никогда не должен возникать.
Итак, ситуации реального мира, в которых я нуждался, включают:
Итак, я хотел бы догадаться, что Reflection не позволил сделать что-то, чего раньше нельзя было сделать. Тем не менее, он делает некоторые типы проблем более легкими для кодирования, более четкими для читателя, короткими для записи и т.д.
Конечно, только мое мнение, я могу ошибаться.
Мне когда-то хотелось иметь модульные тесты в текстовом файле, которые могут быть изменены нетехническим пользователем в формате на С++:
MyObj Function args //textfile.txt
Но я не мог найти способ чтения в строке, а затем создать код экземпляра объекта типа, представленного строкой, без отражения, которое С++ не поддерживает.
char *str; //read in some type from a text file say the string is "MyObj"
str *obj; //cast a pointer as type MyObj
obj = new str; //create a MyObj
Другим вариантом может быть создание универсальной функции копирования, которая могла бы скопировать членов класса, не зная их заранее.
Это очень помогает, когда вы используете в своем коде атрибуты С#, такие как [Устаревшие] или [Serializable]. Такие структуры, как NUnit, используют отражение в классах и содержат методы для понимания того, какие методы являются испытаниями, установкой, разрывом и т.д.