【问题标题】:Visual Studio suggesting fully qualified namespaces when not neededVisual Studio 在不需要时建议完全限定的命名空间
【发布时间】:2012-04-22 20:48:55
【问题描述】:

使用 Visual Studio 2010(也可能是 2008 年)我注意到 Intellisense 会建议枚举的完全限定命名空间的行为。

例如,我可以这样写代码:

element.HorizontalAlignment = HorizontalAlignment.Right;
element.VerticalAlignment = VerticalAlignment.Bottom;

但是当我尝试写它时,它建议我这样写:

element.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
element.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;

这些不必要的额外代码确实会加起来并使其可读性降低,我基本上必须与 Intellisense 作斗争才能避免它。

这是我的理由吗?我可以把它关掉吗?我认为原因是枚举的名称与属性的名称相同。但这真的不是一个很好的理由。

编辑:

这是另一个示例,说明为什么不需要完全限定的命名。

using SomeOtherNamespace;

namespace SomeNamespace
{
    public class Class1
    {
        public Class2 Class2 { get; set; }

        public Class1()
        {
            // These all compile fine and none require fully qualified naming.  The usage is context specific.
            // Intellisense lists static and instance members and you choose what you wanted from the list.

            Class2 = Class2.Default;
            Class2.Name = "Name";
            Class2.Name = Class2.Default.Name;
            Class2 = Class2;
        }
    }
}

namespace SomeOtherNamespace
{
    public class Class2
    {
        public static Class2 Default { get; set; }

        // public static Class2 Class2;  (This throws an error as it would create ambiguity and require fully qualified names.)

        // public static string Name { get; set; }  (This also throws an error because it would create ambiguity and require fully qualified names.

        public string Name { get; set; }
    }
}

【问题讨论】:

  • 引人入胜;据我回忆,VS 从来没有在不需要时建议完全限定的名称。
  • 我之前在 Windows 窗体应用程序中遇到过同样的问题。它建议我编写 System.Windows.Forms.DialogResult.OK 而不仅仅是 DialogResult.OK。同样,我很确定在该范围(表单)中有一个名为“DialogResult”的本地属性。
  • 正确。在这种情况下,我认为这是必需的。
  • 由于上下文关系,它不是必需的,原因与您可以创建一个名为“public Image Image”的属性相同。编写“DialogResult = DialogResult.OK”可以很好地编译,因为没有歧义。不必将其写为“DialogResult = System.Windows.Forms.DialogResult.OK”。
  • 对 Intellisense 而言,它在 那一刻 所关心(知道)的只是 DialogResult,而那在那个时候将是模棱两可的。只有当您添加更多内容时,它才会变得不同。

标签: c# visual-studio intellisense


【解决方案1】:

假设您在WPF 环境中工作(我看到元素)并且您不知何故引用了System.Windows.Forms dll。

我的推论是基于HorizontalAlignment 可以在两个命名空间中找到:

System.Windows.Forms.HorizontalAlignment

System.Windows.FrameworkElement.HorizontalAlignment

有两个指向相同类型的引用,VS 要求指定您的意思确切的命名空间。

【讨论】:

  • 我没有引用 System.Windows.Forms。
  • @Moozhe: 任何Office dll,而不是?
  • 这是一个带有 System、WindowsBase、PresentationFramework 和 PresentationCore 的空项目。
  • 这不是我会得到的行为。如果您尝试引用 System.Windows.Forms 然后添加“使用”我编写的代码,由于歧义,甚至无法编译。
  • @Moozhe:正确,但我不知道提供的代码是否可编译,这就是为什么我有这样的疑问。
【解决方案2】:

这确实是same name for property & the type
这是模仿事物的smallest reproducible example(可能更小,但这揭示了更多)......

namespace Company.Project.SubProject.Area.Test.AndSomeMore
{
    public class TestClass
    {
        public TestEnum MyEnum { get; set; }
        public TestEnum TestEnum { get; set; }
        public SndTestEnum NewEnum { get; set; }
    }
    public enum TestEnum
    {
        None,
        One,
        Two
    }
    public enum SndTestEnum
    {
        None,
        One,
        Two
    }
}
namespace MyCallerNS
{
    public class MyTestClass : TestClass
    {
        public MyTestClass()
        {
            this.TestEnum = Company.Project.SubProject.Area.Test.AndSomeMore.TestEnum.One;
            this.MyEnum = Company.Project.SubProject.Area.Test.AndSomeMore.TestEnum.Two;
            this.NewEnum = SndTestEnum.None;
        }
    }
}

MyEnumTestEnum 属性(以 TestEnum 枚举为目标)都提供“完全限定”名称(其他名称与其属性类型不同,但类型与其他属性名称匹配,因此两者都被“污染”) -而 SndTestEnum 具有不同的命名(用于类型、属性)并且在任何一种情况下都可以正常工作。

...有趣的是,即使您删除 namespace MyCallerNS 并将所有内容放在“长名称空间”下 - 它仍然会在前面添加 AndSomeMore.

我认为没有解决方案(缺少 Re# 和 3rd 方工具),
正如@Rick 建议的那样,这似乎是智能感知不是as smart as the compiler 的情况。

或者更确切地说 - 编译器需要时间来解决问题(手头有所有信息),而智能感知没有那种“深度”和对事物的洞察力(我猜,真的很简化 - 我们需要@Eric :) 并做出快速/最简单的选择。

编辑:实际上,根据我之前的想法,
它更多的是关于每个执行的“工作” - 而智能感知(作为完成“服务”)必须向您提供列表中的所有选择(属性名称和类型)(我不认为它们都是存在,但只是一个猜测。并且有一个选择来涵盖两者可能会很痛苦)
因此,为了区分它添加了完全限定的名称。
它“失败”的地方(有点)是最后“粘贴”了“短版”——我确实应该这么想。

【讨论】:

    【解决方案3】:

    我发现如果我输入element.HorizontalAlignment =,那么VS2010 会自动提示System.Windows.HorizontalAlignment,如果你按下tab 键就会被选中。如果不按 Tab 键,而是键入“Ho”来缩小列表,然后按 Tab,则只会得到 Horizo​​ntalAlignment。

    如果您能够使用Resharper,那么在输入“=”后,您将看到最明显的选择:

    HorizontalAlignment.Center
    HorizontalAlignment.Left
    HorizontalAlignment.Stretch
    HorizontalAlignment.Right
    

    【讨论】:

    • 这可能是正确的答案。我实际上研究了这个问题,发现其他人说 Resharper 没有解决这个问题,但这可能是旧版本或错误信息。我今晚会试试这个。
    • 我使用的是 R# 6.1 和 7。我不记得以前版本中的行为。
    • 我尝试了 R# 6.1 和 7。有趣的是,它破坏了默认的 Intellisense 预选。在 Resharper 选项 -> 环境 -> Intellisense -> Autopopup -> C# 下,它提到了预选作为一个选项,但它没有预选,事实上,即使你选择“显示并且不预选”,行为似乎也是一样的。
    • 如果没有预选,您需要将手移到鼠标单击,或者将手移到箭头键。对于枚举,我习惯于不必把手从主排上移开。例如,键入 Horizo​​ntalAlignment = Horizo​​ntalAlignment.Center 只需 2 次击键即可选择,而无需离开主行键入位置。您只需键入句点,然后键入“C”。
    • 是的,同意。令人讨厌的是,R# 没有在枚举中考虑句点。但是,您可以使用驼峰智能感知。例如输入“= HAC”或“= HAT”。
    【解决方案4】:

    这是编译器比 Intellisense 更智能的情况。

    如果您正在访问与其类型同名的属性,例如“public TextAlignment TextAlignment { get; set; }”,您不需要完全限定分配给它的枚举值的命名空间。但是,Intellisense 似乎还不够聪明,无法知道这一点。代码没有资格也可以正常工作,你只需要善于注意和躲避 Intellisense。

    【讨论】:

    • 你是说 Visual Studio 2005 中的 Intellisense 比 VS 11 中的 Intellisense 更智能吗?我在工作中使用VS2005,从来没有遇到过这个问题,一次也没有。
    • 我不知道?自 2008 年以来,我没有使用 2005 年。
    【解决方案5】:

    除了上面的答案,我还有一些涉及 Microsoft Office 自动化的项目。我的课程结构为

    • CustomNameSpace.Library.Microsoft.Word.CustomClass1
    • CustomNameSpace.Library.Microsoft.Excel.AnotherCustomClass

    当尝试访问 .NET 框架本身的 Microsoft 命名空间中的任何内容时,Intellisense 会强制您完全限定名称。在根冲突的情况下,它还会预先添加全局关键字,如下所示:global::Windows.Forms.etc...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-09
      • 1970-01-01
      • 1970-01-01
      • 2015-09-15
      • 1970-01-01
      • 2019-07-10
      • 2017-12-01
      相关资源
      最近更新 更多