怎么做电玩网站济南网站建设优化百家号

当前位置: 首页 > news >正文

怎么做电玩网站,济南网站建设优化百家号,重庆在线平台,鞍山站文章目录 一、使用 Activator.CreateInstance 创建实例1、使用 Activator.CreateInstance 的优点和缺点2、使用 Activator.CreateInstance 的代码示例 二、使用 Type.InvokeMember 创建实例1、使用 Type.InvokeMember 的优点和缺点2、使用 Type.InvokeMember 的代码示例 三、Ac… 文章目录 一、使用 Activator.CreateInstance 创建实例1、使用 Activator.CreateInstance 的优点和缺点2、使用 Activator.CreateInstance 的代码示例 二、使用 Type.InvokeMember 创建实例1、使用 Type.InvokeMember 的优点和缺点2、使用 Type.InvokeMember 的代码示例 三、Activator.CreateInstance 与 Type.InvokeMember 的基准测试1、反射性能的 BenchmarkDotNet 设置2、Activator.CreateInstance 与 Type.InvokeMember对比 四、Activator.CreateInstance 与 Type.InvokeMember 总结 一、使用 Activator.CreateInstance 创建实例 在 C# 中Activator.CreateInstance方法是开发人员通过反射创建实例的最常用方法之一。它允许在运行时创建类的新实例即使事先不知道它们的具体类型。此方法属于类System.Activator通常用于需要动态实例化的场景。 的主要目的Activator.CreateInstance是动态创建类的实例 — 因此如果您在编译时可以访问该类型那么您可能没有充分的理由使用它Activator.CreateInstance在要创建的对象类型直到运行时才知道的情况下例如在加载插件或使用动态加载的程序集时它特别有用。它消除了对硬编码显式构造函数的需求并提供了对象创建的灵活性。 1、使用 Activator.CreateInstance 的优点和缺点 Activator.CreateInstance与普通对象实例相比使用有几个优点 允许后期绑定对象创建这在对象类型在运行时可能发生变化的情况下很有用。 可以通过消除使用 switch 语句或 if-else 条件来处理不同对象类型的需求来简化代码库。 提供一种动态且可扩展的对象创建方法。 但是使用时也需要考虑一些缺点Activator.CreateInstance 由于运行时解析类型涉及额外的步骤因此与直接实例化相比使用反射的性能开销可能更高。 Activator.CreateInstance 通常依赖于公共无参数构造函数的存在。否则您需要始终知道要传入哪些参数 — 如果您要针对许多不同类型动态执行此操作则具有挑战性。 由于没有编译时检查签名兼容性因此在修改目标类型时容易出现错误。 2、使用 Activator.CreateInstance 的代码示例 以下代码示例演示了如何使用Activator.CreateInstance动态创建实例 // Example 1: Creating an instance of a known type Type objectType typeof(MyClass); object instance Activator.CreateInstance(objectType);在示例 1 中我们使用typeof获取Type代表已知类的对象MyClass。然后我们使用Activator.CreateInstance创建 的新实例MyClass。 // Example 2: Creating an instance of an unknown type at runtime string typeName MyNamespace.MyClass; Type unknownType Type.GetType(typeName); object dynamicInstance Activator.CreateInstance(unknownType);在示例 2 中我们有一个由字符串表示的未知类型typeName。我们使用根据提供的类型名称Type.GetType获取对象。最后用于创建动态确定类型的新实例。TypeActivator.CreateInstance 我们再看一个例子其中我们可以为构造函数传递参数——同样假设我们知道签名因为我们无法在编译时通过这种方法证明它 // Example 3: Creating an instance with constructor parameters: string typeName MyNamespace.MyClass; Type unknownType Type.GetType(typeName); Object dynamicInstance Activator.CreateInstance(unknownType,new[]{Hello World!, // this is the single string parameter!});二、使用 Type.InvokeMember 创建实例 Type.InvokeMember是 DotNet 中 Reflection 提供的一种可用方法允许我们动态创建类型的实例。它提供了一种灵活的方法可以通过利用手头类型的信息在运行时实例化对象。出于这些原因它在如何利用它来创建对象实例方面非常相似。 1、使用 Type.InvokeMember 的优点和缺点 Type.InvokeMember与普通对象实例相比使用以下方法具有一些普遍的优点 允许后期绑定对象创建这在对象类型在运行时可能发生变化的情况下很有用。 可以通过消除使用 switch 语句或 if-else 条件来处理不同对象类型的需求来简化代码库。 提供一种动态且可扩展的对象创建方法。 等一下……这不就是我们上面看到的那个列表吗Activator.CreateInstance没错。所以我们就简短地介绍一下这部分。除非我们开始研究性能否则我们不会看到任何大的差异——也许在某些非常特殊的边缘情况下。但总的来说两者都提供了非常全面的方法来动态实例化对象而 InvokeMember 有点冗长因为它处理的不仅仅是构造函数。 在进行基准测试之前我们先检查一些代码。 2、使用 Type.InvokeMember 的代码示例 下面是一个示例代码片段演示了如何Type.InvokeMember动态创建类型实例 // Example 1: Creating an instance of a known type Type objectType typeof(MyClass); var instance objectType .InvokeMember(null,BindingFlags.CreateInstance,null,null,null);在上面的例子中我们首先获取代表类“MyClass”的 Type 对象。然后我们使用 Type.InvokeMember 创建该类的实例并将其分配给“instance”变量。这使我们能够动态创建“MyClass”的对象而无需明确指定类名。 而在编译时不知道类的情况下执行此操作与以前非常相似。但这部分与 InvokeMember 无关 // Example 2: Creating an instance of an unknown type at runtime string typeName MyNamespace.MyClass; Type unknownType Type.GetType(typeName); var instance objectType.InvokeMember(null,BindingFlags.CreateInstance,null,null,null);最后如果我们需要传递一些构造函数参数那么我们也可以这样做 // Example 3: Creating an instance with constructor parameters: string typeName MyNamespace.MyClass; Type unknownType Type.GetType(typeName); var instance objectType.InvokeMember(null,BindingFlags.CreateInstance,null,null,new[]{Hello World!,});三、Activator.CreateInstance 与 Type.InvokeMember 的基准测试 1、反射性能的 BenchmarkDotNet 设置 我认为我们可以在三种情况下使用 BenchmarkDotNet 运行基准测试 无参数构造函数类 具有单个字符串参数的构造函数 具有单个字符串参数的主构造函数 我想加入主构造函数因为我知道这个特性会招致很多人的反对——最好还是获取一些数据吧以下是我们将要实例化的类供参考 public class ParameterlessClass { }public class ClassicStringParameterClass {private readonly string _value;public ClassicStringParameterClass(string value){_value value;} }public class PrimaryConstructorStringParameterClass(string _value) { }至于基准测试让我们看看我们将要运行的以下类。请记住我使用它Activator.CreateInstance作为基线是因为我想比较Activator.CreateInstancevs Type.InvokeMember— 我只包括正常的构造函数路径作为参考。您也可以在 GitHub 上找到所有这些代码 [ShortRunJob] public class ParameterlessClassBenchmarks {private Type? _type;[GlobalSetup]public void GlobalSetup(){_type typeof(ParameterlessClass);}[Benchmark]public void Constructor(){var instance new ParameterlessClass();}[Benchmark(Baseline true)]public void Activator_Create_Instance(){var instance Activator.CreateInstance(_type!);}[Benchmark]public void Type_Invoke_Member(){var instance _type!.InvokeMember(null,BindingFlags.CreateInstance,null,null,null);} }[ShortRunJob] public class ClassicStringParameterClassBenchmarks {private Type? _type;[GlobalSetup]public void GlobalSetup(){_type typeof(ClassicStringParameterClass);}[Benchmark]public void Constructor(){var instance new ClassicStringParameterClass(Hello World!);}[Benchmark(Baseline true)]public void Activator_Create_Instance(){var instance Activator.CreateInstance(_type!,new[]{Hello World!,});}[Benchmark]public void Type_Invoke_Member(){var instance _type!.InvokeMember(null,BindingFlags.CreateInstance,null,null,new[]{Hello World!,});} }[ShortRunJob] public class PrimaryConstructorStringParameterClassBenchmarks {private Type? _type;[GlobalSetup]public void GlobalSetup(){_type typeof(PrimaryConstructorStringParameterClass);}[Benchmark]public void Constructor(){var instance new PrimaryConstructorStringParameterClass(Hello World!);}[Benchmark(Baseline true)]public void Activator_Create_Instance(){var instance Activator.CreateInstance(_type!,new[]{Hello World!,});}[Benchmark]public void Type_Invoke_Member(){var instance _type!.InvokeMember(null,BindingFlags.CreateInstance,null,null,new[]{Hello World!,});} }2、Activator.CreateInstance 与 Type.InvokeMember对比 当我们将这两种反射方法进行对比时获胜者是…视情况而定。在最常见的一种情况下我会说有一个非常明显的赢家但对于其他情况它们非常接近。但请务必阅读结论因为这不是故事的结局。 我们要研究的第一个基准是无参数构造函数
Activator.CreateInstance 与 Type.InvokeMember - 无参数构造函数的基准 这里明显胜出Activator.CreateInstance几乎高出一个数量级。如果你的构造函数没有任何参数那么最好的选择就是这个。 接下来让我们检查Activator.CreateInstance一下Type.InvokeMember接受单个字符串参数的构造函数
Activator.CreateInstance 与 Type.InvokeMember - 带参数的经典构造函数的基准 这两款车基本上势均力敌尽管Activator.CreateInstance略胜一筹但差距几乎可以忽略不计。 要查看的最后一个场景是主构造函数在本例中主构造函数接受一个字符串参数
Activator.CreateInstance 与 Type.InvokeMember - 主构造函数的基准 获胜者Type.InvokeMember但只领先一点点。非常有趣的是这与我们在之前的基准测试中看到的结果相反 四、Activator.CreateInstance 与 Type.InvokeMember 总结 当谈到Activator.CreateInstancevs的性能结果时Type.InvokeMember无参数构造函数的情况明显胜出Activator.CreateInstance。但是当我们开始需要参数或使用带参数的主构造函数时它开始均衡甚至有利于Type.InvokeMember。