这是我前一个问题的链接,这引导我进入这个问题。 C# Nested foreach loop optimization
计算时间仍然很长,我不确定原因是什么。
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);
}
}
答案 0 :(得分:3)
如果计算时间明显变慢,我猜你会大量调用这段代码而且你正在编译许多你在编译时不太了解的对象。
不要将类保留在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();
的内容
这是我所知道的最简单方法,因为显然你是can't get a delegate to a constructor。
如果您编写自己正在创建的类,则可以使用创建一个类的方法创建公共基类或接口,这样就可以将委托保留给该构造函数,这样更快。
This post也有一些有趣的想法,可以进一步优化更多。如果你想快速做到这一点,你可以。几乎和调用new KnownClass()
GJ
答案 1 :(得分:1)
总结:基本上无限制的循环与每次迭代中调用的框架中最慢的函数之一将会很慢。
有多种方法可以避免反思,但没有任何其他信息,你只需要忍受它。
答案 2 :(得分:0)
使用Dictionary.TryGetValue一次查找“name”键而不是两次。这只是一个小小的提示,因为我确信反思是瓶颈。