Здесь была ссылка на предыдущий вопрос, который привел меня к этому. С# Вложенная оптимизация цикла foreach
По-прежнему существует большое время вычисления, и я не уверен, в чем причина.
object foo;
List<string> StringList = new List<string>(); // Populated by previous code
Dictionary<string, Type> assemblyTypes = RandomAssembly.GetTypes().ToDictionary(t => t.Name, t => t);
foreach (String name in StringList)
{
if (assemblyTypes.ContainsKey(name))
{
// Create an instance of the matching class and add it
// to the appropriate lists.
Type at = assemblyTypes[name];
foo = Activator.CreateInstance(at);
ArbitraryList1.Add(foo);
}
}
Если время вычисления заметно медленное, я предполагаю, что вы часто вызываете этот код, и вы создаете множество объектов, о которых вы мало что знаете во время компиляции.
Вместо того, чтобы держать классы в Dictionary<string, type>
и вызывать CreateInstance
, вы хотите сохранить словарь своих конструкторов Dictionary<string, ConstructorInfo>
, чтобы вы могли напрямую ихзывать, не задумываясь при каждом его отражении.
Таким образом вы можете просто вызвать AssemblyConstructors [Name].Invoke(), чтобы создать новый экземпляр класса.
Таким образом вам нужно только один раз использовать отражение, чтобы найти конструкторы.
// keep a dictionary of constructors (instead of the types)
var Constructors = new Dictionary<string, ConstructorInfo>();
// add this class to this dictionary
Type t = typeof(SomeClass);
string name = t.Name;
Constructors[name] = t.GetConstructors()[0]; // use reflection only once here, afterwards we reuse the reflected info
// new up an instance
var o = Constructors[name].Invoke(new object[] {});
Я думаю, что первый конструктор будет без параметров. Попробуйте что-то вроде t.GetConstructors().Where(x => x.GetParameters().Count() == 0).First();
Это самый быстрый способ, который я знаю, потому что, по-видимому, вы не можете получить делегата для конструктора.
Если вы пишете классы, которые вы создаете сами, у вас может быть общий базовый класс или интерфейс с методом, который создает его, таким образом вы можете сохранить делегат этого конструктора, что еще быстрее.
Удачи,
ГДж
Резюме: существенно неограниченный цикл с одной из самых медленных функций в структуре, называемой каждой итерацией, будет медленным.
Существует множество подходов, чтобы избежать отражения, но без какой-либо другой информации, с которой вам просто нужно жить.
Используйте Dictionary.TryGetValue, чтобы искать ключ "имя" один раз вместо двух. Это всего лишь маленький наконечник, поскольку я уверен, что отражение является узким местом.