【问题标题】:Instantiating object with full name用全名实例化对象
【发布时间】:2019-12-05 17:29:06
【问题描述】:

快速的理论问题。我有以下代码:

if (partnership != null && partnership.UseCustomNotifier)
{
    //some behavior
}
else
{
    Integration.Protocol.Client.Notifier protocolNotifier = new Integration.Protocol.Client.Notifier();
}   

我有两个使用反射选择的伙伴关系实现。 Integration.Protocol 不在 usings 中。应动态选择实施;问题是,如果我评论最后一行(protocolNotifier 的实例化),它只会选择一种实现(不是来自 Integration.Protocol 的实现,因为它是唯一可用的)。否则,它将使用反射动态选择。

我知道这段代码很糟糕(我已经对其进行了改进),但我很好奇为什么会出现这种行为。我猜想当解决方案在运行之前编译时,它会检查protocolNotifier 被实例化的那一行,并在编译时添加使用。它是否正确?它只发生在方法的范围内吗?还是全班?我很好奇 .NET 编译器在这些情况下是如何工作的。

【问题讨论】:

  • “动态”是什么意思。您显示的代码中没有任何反射,但代码看起来确实像工厂方法/类。该类不再可用,因为您从方法中删除了它(我假设)。我想我得到的是您发布的代码与您的问题不匹配。你想在这里完成什么?
  • 它不会在编译时添加usingusing <namespace> 只是为了让您不必每次都输入完全限定的名称。编译的 IL 代码使用完全限定名称。看看你的 IL 代码,自己看看

标签: c# asp.net .net visual-studio compilation


【解决方案1】:

如果我理解正确的话:

  • partnership 是一个类型的对象,通过使用反射来查找具有该名称的所有可用类(我们将其称为 Partnership)并创建一个找到的类型的对象
  • Integration.Protocol 命名空间有一个名为 Partnership 的类(或任何实际名称),但在此项目的代码或您已在其他地方使用的其他库中还有另一个名为 Partnership 的类
  • 根据您是否包含最后一行,您的反射代码会选择其中一个

如果我在这方面是正确的,那么我相信您看到的行为仅仅是因为它正在加载 Integration.Protocol 库(假设它是一个单独的 DLL,实际上并不是当前项目代码的一部分)。

如果您向我们展示您如何设置partnership 的代码,那么我们可以确认这一点。但是,如果我是正确的,那么如果您没有在最后一行中使用 Integration.Protocol,那么根本不会加载该库,并且您的反射代码将无法从该库中找到任何内容。

这不是“在编译时添加using”,因为using 语句只允许您在引用类时不包含命名空间。它与是否在运行时加载库没有任何关系。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多