【问题标题】:Wouldn’t Type.CreateInstance made more sense than Activator.CreateInstance?Type.CreateInstance 不是比 Activator.CreateInstance 更有意义吗?
【发布时间】:2010-03-09 19:24:30
【问题描述】:

1) 如果我们想在运行时创建给定类型的实例(因此使用后期绑定),那么我们需要调用 Activator.CreateInstance。但是如果Type类有这样的方法不是更高效吗?如果不出意外,Type.CreateInstance 可以返回强类型实例而不是 System.Object?!

2) Type.GetType 使我们只能将包含该类型的程序集的友好名称传递给它,因此它不允许我们指定该程序集的绝对路径。

知道为什么 Type.GetType 允许我们指定程序集的绝对路径是个坏主意吗?

感谢

【问题讨论】:

    标签: c#


    【解决方案1】:

    Type 有一个目的:它在运行时环境中定义了一个唯一的“类型”。

    Activator 保留为单独的类型,以及将 Assembly 保留为程序集信息,是一件好事。拥有定义单一用途和用途的小类是更好的设计。

    Activator.CreateInstance 移动到 Type 不会提高效率 - 它可能更容易在您的特定场景中概念化,但它会导致类型变得更大更复杂。我个人觉得当前的设计非常干净和漂亮,并且很高兴他们保持 Type 类唯一用于定义类型,并将其他信息(如程序集信息和构造)留在单独的类型中。

    【讨论】:

      【解决方案2】:

      关于为什么 Type.GetType 不允许您指定程序集的完整路径的问题,我们再次回到单一责任原则。 Assembly.Load 是您加载程序集的方式,Type.GetType 仅适用于当前加载的程序集。

      【讨论】:

        【解决方案3】:

        1) 你可以,但我不确定这些是否比使用 Activator.CreateInstance 更好

        object obj = someType.GetConstructor(Type.EmptyTypes).Invoke(null);
        object obj = someType.InvokeMember("", BindingFlags.CreateInstance, null, null, null);
        

        2) 如here 所述,未使用完整的程序集限定名称来加载可能的意外类型并可能产生奇怪的结果。

        指定加载程序集的位置是只有 Assembly.LoadFrom 的事情。 Assembly.LoadFrom 在较新的 .Net 版本中已弃用。原因是当您使用 LoadFrom 时,您确实需要知道程序集是在不同的上下文中加载的,unexpected 的事情可能会发生。所以 Type.GetType 没有这样的功能是好事。

        【讨论】:

        • “我不确定你所说的绝对路径是什么意思,因为从指定位置加载程序集只有 Assembly.LoadFrom 可以做到。”通过绝对路径,我的意思是 C:\SomeApp\Assembly.dll
        • 所以答案是:这不是一个好主意,因为这些程序集是在不同的上下文中加载的。见hanselman.com/blog/…
        • 呃,我跳过了书中讨论上下文的部分,以为我不必知道。
        【解决方案4】:
        1. 激活类型可能需要与 COM 互操作和远程处理一起使用,因此使用类型来处理这个问题会将太多的鸡蛋放在一个篮子里(也就是糟糕的设计)。您确实有 Activator.CreateInstance(),但您需要在编译时知道类型。

        【讨论】:

          【解决方案5】:

          嗯,你可以,只需要多跳一跳。您可以使用 Type.GetConstructor() 并调用返回的 ConstructorInfo.Invoke() 方法。

          Type.GetType() 也将采用程序集限定名称。或者您可以使用 Assembly.Load() 和 Assembly.GetType() 来获取 Type 实例。

          【讨论】:

          • "Type.GetType() 也将采用程序集限定名称。"我意识到了。但是为什么 Type.GetType 也不能让我们指定程序集的路径?
          • 因为从绝对路径加载程序集的情况非常很少见。如果你必须这样做,那么你可以通过 Assembly.LoadFile() 多跳一次。不惜一切代价避免这种情况。
          【解决方案6】:

          使用反射,您还可以搜索正确的 ConstructorInfo 并为您的类型调用它,然后您将获得一个强类型实例并能够后期绑定它。

          编辑 ConstructorInfo.Invoke(object[])
          它不是强类型的,在使用 T 类型的新实例之前必须进行类型转换。

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-03-02
          • 2011-01-09
          • 1970-01-01
          • 1970-01-01
          • 2023-01-04
          • 1970-01-01
          • 2022-06-16
          相关资源
          最近更新 更多