Хотя есть много хороших объяснений выше, я пропускаю практический способ разделения шаблонов на заголовок и тело. Моя главная задача - избегать перекомпиляции всех пользователей шаблонов, когда я меняю свое определение. Все экземпляры шаблонов в корпусе шаблона не являются жизнеспособным решением для меня, поскольку автор шаблона может не знать всех, если его использование и пользователь шаблона могут не иметь права его модифицировать. Я принял следующий подход, который также работает и для более старых компиляторов (gcc 4.3.4, aCC A.03.13).
Для каждого использования шаблона в его собственном файле заголовка (сгенерированном из модели UML) имеется typedef, , Его тело содержит экземпляр (который заканчивается в библиотеке, которая связана в конце). Каждый пользователь шаблона включает этот файл заголовка и использует typedef.
Схематический пример:
MyTemplate.h:
#ifndef MyTemplate_h
#define MyTemplate_h 1
template <class T>
class MyTemplate
{
public:
MyTemplate(const T& rt);
void dump();
T t;
};
#endif
MyTemplate.cpp:
#include "MyTemplate.h"
#include <iostream>
template <class T>
MyTemplate<T>::MyTemplate(const T& rt)
: t(rt)
{
}
template <class T>
void MyTemplate<T>::dump()
{
cerr << t << endl;
}
MyInstantiatedTemplate.h:
#ifndef MyInstantiatedTemplate_h
#define MyInstantiatedTemplate_h 1
#include "MyTemplate.h"
typedef MyTemplate< int > MyInstantiatedTemplate;
#endif
MyInstantiatedTemplate.cpp:
#include "MyTemplate.cpp"
template class MyTemplate< int >;
main.cpp:
#include "MyInstantiatedTemplate.h"
int main()
{
MyInstantiatedTemplate m(100);
m.dump();
return 0;
}
Таким образом, нужно будет перекомпилировать только экземпляры шаблонов, не всех пользователей шаблонов (и зависимостей).
Есть разница между пустой ссылкой и пустой коллекцией. Можно вызвать Take для пустой коллекции. И аргумент указывает максимальное число, которое нужно взять, поэтому также можно указать большее количество элементов, чем имеется в коллекции.
Я рекомендую обратиться к MSDN для получения более подробной информации, подобной этой.
Для Linq to Objects: http://msdn.microsoft.com/en-us/library/bb503062.aspx[1210ptingFor Ссылка на базы данных: http://msdn.microsoft.com/en-us/library/bb300906.aspx
Это исключение нулевой ссылки возникает только в том случае, если вы делаете это с источником объекта, например:
List<MyObject> myList = null;
myList.Take(5); // this would produce the error, of course
Когда вы выполняете Linq to SQL, он вернет ПУСТОЙ перечислитель ваших данных, а не пустая ссылка. Точно так же, если вы пытаетесь взять больше, чем доступно, это займет только доступную сумму. Я использую этот метод для страниц данных в некоторых случаях и определенно часто, когда я прошу больше записей, чем имеется в списке.
Выполнить исключение, если вызывающий его объект имеет значение NULL. Скорее всего, у вас не будет нулевого объекта, а отсутствие или меньшее количество строк - это не то же самое (я уверен, что вы понимаете семантику).
Если вы используете контекст Linq to SQL и выполняете запросы в стиле
Context.MyTable.Where(x => x.ID > 0).Take(2);
] в случае Где
возвращает нулевые результаты, вы не получите нулевое исключение, потому что ваш запрос еще не был выполнен, то в случае, если он содержит только 1 результат, вы получите только 1 результат. Take
ограничивает количество возвращаемых записей.
Подсчитайте количество элементов перед вызовом Take ():
List<string> a = new List<string>();
int count = a.Count > 12 ? 12 : a.Count;
a.Take(count);