Visual Studio предлагает полностью квалифицированные пространства имен, когда это не требуется

С 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, чтобы избежать его.

Есть ли у меня причина для этого? Могу я просто отключить его? Я предполагаю, что причина в том, что имя перечисления совпадает с именем свойства. Но это действительно не очень хорошая причина.

EDIT:

Вот еще один пример, который показывает, почему полное именование не требуется.

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; }
    }
}

Ответы

Ответ 1

Это действительно похоже на 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;
        }
    }
}

Оба свойства MyEnum и TestEnum (target TestEnum enum) предлагают "полностью квалифицированные" имена (другое имеет другое имя, чем его тип свойства, но тип совпадает с другим именем свойства, поэтому оба являются "испорченными" ) в то время как SndTestEnum имеет различное именование (для типа, свойства) и отлично работает в любом случае.

... Смешно, что даже если вы удалите namespace MyCallerNS и поместите все под "длинным пространством имен" - он все равно добавит AndSomeMore. спереди.

Нет решения, поскольку я вижу его (без инструментов Re # и сторонних разработчиков),
это кажется, что intellisense не является случаем as smart as the compiler, как предложил @Rick.

Или, скорее, компилятор не спешит решать проблемы (со всей информацией в руках), в то время как intellisense не имеет этой "глубины" и понимания вещей (я предполагаю, упрощая на самом деле - нам нужно @Eric на этом:) и делает быстрый/простой выбор.

EDIT: Собственно, по моей предыдущей мысли,
это больше о "задании", которое выполняют каждый из них, и intellisense (как услуга "завершение" ) должно предоставить вам все варианты (как имя свойства, так и тип) в списке (я не вижу, чтобы они оба были настоящее, но предположение. И иметь один выбор, чтобы покрыть оба, вероятно, будет болью, чтобы справиться)
Таким образом, чтобы дифференцировать, он добавляет полностью квалифицированные имена.
И там, где это "не удается" (вроде), нужно "вставить" "короткую версию" в конце, что и должно быть.

Ответ 2

Я полагаю, вы работаете в среде WPF (я вижу элемент), и у вас есть ссылка на System.Windows.Forms dll.

Мой вывод основан на факте, что HorizontalAlignment можно найти в обоих пространствах имен:

в System.Windows.Forms.HorizontalAlignment

и

в System.Windows.FrameworkElement.HorizontalAlignment

Имея две ссылки, указывающие на один и тот же тип, VS просит указать, какое пространство имен именно вы имеете в виду.

Ответ 3

Я нахожу, если я наберу element.HorizontalAlignment =, тогда VS2010 автоматически предложит System.Windows.HorizontalAlignment, который будет выбран, если вы нажмете клавишу табуляции. Если вместо нажатия клавиши tab вы набираете "Ho", чтобы сузить список, а затем нажмите вкладку, вы просто получите HorizontalAlignment.

Если вы можете использовать Resharper, то после ввода '=' вам будут представлены наиболее очевидные варианты:

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

Ответ 4

Это случай, когда компилятор умнее Intellisense.

Если вы получаете доступ к свойству с тем же именем, что и его тип, например. "public TextAlignment TextAlignment {get; set;}", вам не нужно полностью квалифицировать пространство имен присвоенного ему значения перечисления. Но Intellisense не кажется достаточно умным, чтобы это знать. Код будет отлично работать без квалификации, вам просто нужно хорошо заметить и уклониться от Intellisense.

Ответ 5

В дополнение к ответам выше, у меня были некоторые проекты, в которых задействована Microsoft Office Automation. Мои классы были структурированы как

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

При попытке получить доступ к чему-либо в пространстве имен Microsoft самой платформы .NET, Intellisense заставит вас полностью квалифицировать имена. В случае конфликта с корнем он также предварительно закроет глобальное ключевое слово так: global::Windows.Forms.etc....