В настоящее время у меня есть статический фабричный метод:
public static Book Create(BookCode code) {
if (code == BookCode.Harry) return new Book(BookResource.Harry);
if (code == BookCode.Julian) return new Book(BookResource.Julian);
// etc.
}
Причина, по которой я их никак не кэширую, заключается в том, что BookResource чувствителен к культуре, которая может меняться между вызовами. Изменения в культуре должны отражаться в возвращаемых объектах книги.
Выполнение этих операторов if может стать узким местом в скорости. Но что, если мы сопоставим коды книг с анонимными функциями/делегатами? Что-то вроде следующего:
delegate Book Create();
private static Dictionary<BookCode, Delegate> ctorsByCode = new Dictionary<BookCode, Delegate>();
// Set the following somewhere
// not working!
ctorsByCode[BookCode.Harry] = Create () => { return new Book(BookResource.Harry); }
// not working!
ctorsByCode[BookCode.Julian] = Create () => { return new Book(BookResource.Julian); }
public static Book Create(BookCode code) {
return (Book)ctorsByCode[code].DynamicInvoke(null);
}
Как я могу заставить эти Create() => {
строки действительно работать?
Стоит ли это того с точки зрения скорости, когда есть ‹50 книжных кодов (таким образом, ‹50 if-операторов)?
Это аналогичный вопрос, но, к сожалению, автор не публикует свой код Enum, коллекция словарей делегатов, где делегат указывает на перегруженный метод
Обновить
Сделал некоторые тесты производительности, если против делегатов. Я выбрал код устройства случайным образом и использовал одно и то же начальное число для обоих методов. Версия делегата на самом деле немного медленнее. Эти делегаты вызывают некоторые накладные расходы. Я использовал релизные сборки для прогонов.
5000000 iterations
CreateFromCodeIf ~ 9780ms
CreateFromCodeDelegate ~ 9990ms