Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EditorBrowsable(EditorBrowsableState.Never) in VS 2015 does not work as well as it does in VS 2013 #4434

Open
TyreeJackson opened this issue Aug 7, 2015 · 44 comments
Labels
4 - In Review A fix for the issue is submitted for review. Area-IDE Bug help wanted The issue is "up for grabs" - add a comment if you are interested in working on it
Milestone

Comments

@TyreeJackson
Copy link

Problem

Consider the following projects and classes:

ProjectA

is not included in the solution

namespace ProjectA
{

    using System;
    using System.ComponentModel;

    public class BaseClass
    {
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new Type GetType() { return base.GetType(); }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public new static bool Equals(object objA, object objB) { return Object.Equals(objA, objB); }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public override bool Equals(object obj)  { return base.Equals(obj); }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public override int GetHashCode() { return base.GetHashCode(); }

        [EditorBrowsable(EditorBrowsableState.Never)]
        protected new object MemberwiseClone() { return base.MemberwiseClone(); }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public new static bool ReferenceEquals(object objA, object objB) { return Object.ReferenceEquals(objA, objB); }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public override string ToString() { return base.ToString(); }

        public static void DoSomeBasicThing() {}

    }

}

namespace ProjectA
{

    public class ClassA : BaseClass
    {

        public static void InitializeClassA() { }

        public void DoSomethingA() {}

    }

}

ProjectB

is included in the solution; has a binary reference to ProjectA

namespace ProjectB
{

    using System.ComponentModel;
    using ProjectA;

    [EditorBrowsable(EditorBrowsableState.Never)]
    public class ClassB : BaseClass, IInterfaceA<ClassB>
    {

        public void DoSomethingB()
        {
            var objectA = new ClassA();
        }

    }

}

ProjectC

is included in the solution; has a binary reference to ProjectA; has a project reference to ProjectB

namespace ProjectC
{

    using ProjectB;

    public class ClassC 
    {

        public void TestEm()
        {
            var objectB  = new ClassB();
        }

    }

}

In Visual Studio 2013 the EditorBrowsable attribute is honored correctly for members of types defined in assemblies that are included using a binary reference. However, in Visual Studio 2015, some of the methods defined on the System.Object [static Equals, static ReferenceEquals, and GetType] appear in the Intellisense menu despite being marked with the EditorBrowsable attribute with the EditorBrowsableState.Never argument in a sub class via new hiding methods.

Here are some screenshots:

Visual Studio 2013 - viewing ProjectA.ClassA's Intellisense menu from ProjectB.ClassB: Visual Studio 2015 - viewing ProjectA.ClassA's Intellisense menu from ProjectB.ClassB:
Visual Studio 2013 - viewing ProjectA.ClassA's Intellisense menu from ProjectB.ClassB Visual Studio 2015 - viewing ProjectA.ClassA's Intellisense menu from ProjectB.ClassB
Visual Studio 2013 - viewing objectA's Intellisense menu from ProjectB.ClassB: Visual Studio 2015 - viewing objectA's Intellisense menu from ProjectB.ClassB:
Visual Studio 2013 - viewing objectA's Intellisense menu from ProjectB.ClassB Visual Studio 2015 - viewing objectA's Intellisense menu from ProjectB.ClassB
Visual Studio 2013 - viewing ProjectB.ClassB's Intellisense menu from ProjectC.ClassC: Visual Studio 2015 - viewing ProjectB.ClassB's Intellisense menu from ProjectC.ClassC:
Visual Studio 2013 - viewing ProjectB.ClassB's Intellisense menu from ProjectC.ClassC Visual Studio 2015 - viewing ProjectB.ClassB's Intellisense menu from ProjectC.ClassC
Visual Studio 2013 - viewing objectB's Intellisense menu from ProjectC.ClassC: Visual Studio 2015 - viewing objectB's Intellisense menu from ProjectC.ClassC:
Visual Studio 2013 - viewing objectB's Intellisense menu from ProjectC.ClassC Visual Studio 2015 - viewing objectB's Intellisense menu from ProjectC.ClassC

Note that this is the additional problem I mentioned in #4358 in the footnote of this comment.

@hmahajanHM
Copy link

Is this fixed? I can still see this bug on VS 2015 Professional Update 1 build 14.0.24720.00

@jcansdale
Copy link

jcansdale commented Oct 20, 2016

The NUnit team is suffering from this issue when developing our Assert API. We'd like to hide Equals, to prevent users from accidentally entering the following:

Assert.Equals(a, b);
Assert.That(a, Is.Equals...

When they should have entered:

Assert.AreEqual(a, b);
Assert.That(a, Is.EqualTo(b));

The following appears to work fine in Visual Studio 2013:

        [EditorBrowsable(EditorBrowsableState.Never)]
        new public static bool Equals(object ob1, object ob2)
        {
            throw new NotImplementedException("I'm afraid I can't do that");
        }

        [EditorBrowsable(EditorBrowsableState.Never)]
        new public static bool ReferenceEquals(object ob1, object ob2)
        {
            throw new NotImplementedException("I'm afraid I can't do that");
        }

But no longer works in Visual Studio 2015:

equals

You can find the issue here:
nunit/nunit#1726 (comment)

See also:
https://twitter.com/jcansdale/status/788704315695398912 😉

@kornelijepetak
Copy link

I don't understand why this is so hard to fix?
It should be a piece of cake now that Intellisense already got filtering by types, methods, properties, etc.

Is this a VS thing, or Roslyn? Which system is responsible for Intellisense population?

@sebastianbk
Copy link

So that's up with this? It was added to the 2.0 milestone but appears to still be an issue. Is there any work for a fix going on regarding this bug?

@ryo0ka
Copy link

ryo0ka commented Sep 3, 2017

Any update?

@sharwell sharwell modified the milestones: 15.5, Unknown Sep 3, 2017
@CyrusNajmabadi CyrusNajmabadi added the help wanted The issue is "up for grabs" - add a comment if you are interested in working on it label Sep 3, 2017
@CyrusNajmabadi
Copy link
Member

@ryo0ka PRs welcome :)

@sharwell sharwell added this to Community Priority in IDE: sharwell Sep 6, 2017
@sharwell sharwell moved this from Community Priority to Internal Priority in IDE: sharwell Sep 6, 2017
@sharwell sharwell self-assigned this Sep 7, 2017
@sharwell
Copy link
Member

sharwell commented Sep 7, 2017

@dpoeschl and I are interested in seeing this completed, but it doesn't currently fix into our scheduling. I'm hoping a community user picks it up so it can ship in 15.5.

Requirements

  • Define the intended behavior
    • Target item is in the current project
    • Target item is found via a project reference
    • Target item is found via an assembly (metadata) reference
  • Locally experiment with Visual Studio 2013 to identify any differences between the intended behavior and the behavior you observe in Visual Studio 2013
  • Post results of intended behavior and Visual Studio 2013 experiments here for review/sign-off (feel free to copy from the original bug report comment where it helps, but review text for accuracy)
  • Implement the completion filtering according to the intended behavior
  • Implement tests covering each of the intended behavior scenarios

Time requirement

This will probably take a new user up to a week or more, or an experienced user a few days.

Work would need to start within the next week to ensure time for this to ship in 15.5 (the earliest release where it would currently be possible).

Interested?

If you are interested, please let us know. If more than one person is interested, that would be acceptable for this issue. In particular, it will be good to have more than one person test the intended behavior in Visual Studio 2013, and more than one person review the test cases to ensure they accurately represent the intended behavior so we do not regress in the future.

@jinujoseph jinujoseph removed this from the 15.5 milestone Oct 14, 2017
@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Jan 28, 2021

@kzu everyone is chock full of a ton of work to do. If you could help out, it would be very valuable and appreciated.

@sharwell
Copy link
Member

The problem here is the implementations we want are in the compiler and do not have any public API surface.

@kzu
Copy link
Contributor

kzu commented Jan 28, 2021

Totally understood @CyrusNajmabadi, as a maintainer of oss myself, I know that's pretty much always the case 😢 .

@sharwell I suppose that makes it a plus rather than a problem? 😉

@jnm2
Copy link
Contributor

jnm2 commented Feb 17, 2021

Source generators are making this more painful. Mentioned in #44929 and a community member was asking about it on Gitter.

@jods4
Copy link

jods4 commented Feb 17, 2021

I am the surprised community member :)

In my case the EditorBrowsable.Never properties were internal.

As internal members are never visible outside their own project, I think it's clear that the intention here was to hide them even in the project that declares them.

I suppose EditorBrowsableState.Never + internal could be ruled as hidden in IDE, even in same project.

(For context, this is inside generated code, marked with <auto-generated> at top of file.)

@sharwell
Copy link
Member

@jods4 The EditorBrowsable attribute was never design to handle that case, so it would be a new feature request that isn't a copy of this bug report. Can you file it separately?

@jnm2
Copy link
Contributor

jnm2 commented Feb 17, 2021

My bad, I didn't realize the in-same-project vs in-same-solution distinction was important.

@jods4
Copy link

jods4 commented Feb 17, 2021

@sharwell I am not sure why you say this isn't the right issue and why the attribute was never designed to handle that case.

The MSDN doc says this about the attribute:

EditorBrowsableAttribute is a hint to a designer indicating whether a property or method is to be displayed. You can use this type in a visual designer or text editor to determine what is visible to the user. For example, the IntelliSense engine in Visual Studio uses this attribute to determine whether to show a property or method.

And that's what I'm using it for: I wanted to hide a member from Intellisense.

This issue seems to be about the fact that VS doesn't respect EditorBrowsable from source code in the current solution.

This is what I experimented: I was surprised the member was showing in Intellisense, then found out that it's because it was in the same solution.

(Admittedly MSDN does point out this limitation, I just didn't read everything thoroughly:)

In Visual C#, EditorBrowsableAttribute does not suppress members from a class in the same assembly.

I can still open a new spin-off issue if you think it's worth it.

@sharwell
Copy link
Member

sharwell commented Feb 17, 2021

@jods4 This issue tracks fixing a bug where the behavior of the attribute changed in Visual Studio 2015 relative to Visual Studio 2013. The cause of the behavior change, and the resulting behavior after the bug is fixed are both well understood. However, the behavior change requested in #4434 (comment) does not align with the behavior of the feature in any previous version of Visual Studio, making it a separate request; if it isn't tracked as a separate issue it's likely to be lost once this issue is fixed.

@CyrusNajmabadi
Copy link
Member

This is what I experimented: I was surprised the member was showing in Intellisense, then found out that it's because it was in the same solution.

Note that this behavior is very intentional and is explicitly what we have been asked to deliver in the past. At one point we did actually hide these items (even in the same project), but the feedback was overwhelming that this is not what teams wanted. They wanted a way to have apis they could see and use, but which their external consumers would not see.

Changing this behavior would not be acceptable as this would regress this feature for all teams currently using it in this fashion.

sonnemaf added a commit to sonnemaf/dotnet-api-docs that referenced this issue Sep 2, 2021
It said does not suppress members from a class in the same ``assembly``.  This must be ``solution``. This changed from VS2013 to VS2015. See dotnet/roslyn#4434
@YegorStepanov
Copy link

YegorStepanov commented Feb 9, 2022

The proposal that hides Equals and ReferenceEquals for all static types: #59333

@CyrusNajmabadi
Copy link
Member

@YegorStepanov that does not seem to be related to this issue.

@YegorStepanov
Copy link

@CyrusNajmabadi My suggestion closes some cases of this problem without writing [EditorBrowsable]

2/4 cases will be automatically closed:

image

image

The third comment will closed too: #4434 (comment)

@dessyordanova
Copy link

This is still an issue in VS 2022 :-(

@CyrusNajmabadi
Copy link
Member

@dessyordanova see #4434 (comment)

kzu added a commit to devlooped/Merq that referenced this issue Nov 11, 2022
Remove also rather useless IFluentInterface since it's not really working as pre-VS2013 (see dotnet/roslyn#4434)
@komdil
Copy link

komdil commented Feb 13, 2023

What is the status of this issue? Is there any progress or PR?

@CyrusNajmabadi
Copy link
Member

@komdil see #4434 (comment)

@komdil
Copy link

komdil commented Feb 13, 2023

@komdil see #4434 (comment)

I didn't understand, is this something that will not be implemented? In that comments, there are some requirements, but I am not seeing any PR and the issue is still opened

@CyrusNajmabadi
Copy link
Member

@komdil

As above, we woudl be willing to take a contribution here that matches the change that Sam laid out.

We would take a contribution to apply the design if a motivated party were to provide it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4 - In Review A fix for the issue is submitted for review. Area-IDE Bug help wanted The issue is "up for grabs" - add a comment if you are interested in working on it
Projects
IDE: sharwell
Internal Priority
Development

No branches or pull requests