EditorBrowsableState.Never für Extension-Methods

    • VB.NET

    Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von Niko Ortner.

      EditorBrowsableState.Never für Extension-Methods

      Neulich schnappte ich eine Erfreulichkeit bei Stackoverflow auf.

      Zuerst mal die Unerfreulichkeit: Vb.Net-Module machen ihre Public Member ja ohne Qualifizierung des Modul-Namens sichtbar.
      Was ein schlimmes FehlDesign ist, denn dadurch bietet Intellisense diese Member an, und das ist nicht lustig, wenn man sich mit der Zeit viele Extension-Functions zu verschiedensten Zwecken angelegt hat, und jede dieser Methoden (das können hunderte sein) ist zugegen, wann immer Intellisense den DropDown anzeigt.

      So, jetzt aber die Erfreulichkeit: Man kann das ganze Extension-Modul aus der Intellisense "heraus-attributieren" - ich zeig einfach mal gleich 2 Module, eines davon entsprechend attributiert:

      VB.NET-Quellcode

      1. Imports System.Runtime.CompilerServices
      2. Imports System.ComponentModel
      3. <EditorBrowsable(EditorBrowsableState.Never)> _
      4. Public Module InvisibleExtensions
      5. <Extension()> _
      6. Public Function StringExtension1(s As String) As String
      7. Return "InvisibleExtensions.StringExtension1"
      8. End Function
      9. End Module
      10. Public Module VisibleExtensions
      11. <Extension()> _
      12. Public Function StringExtension2(s As String) As String
      13. Return "VisibleExtensions.StringExtension2"
      14. End Function
      15. End Module
      Der Screenshot zeigt, was ich meine:

      Beides sind funktionierende Extension-Functions, aber StringExtension1() fährt im Gegensatz zu StringExtension2() nicht inne Intellisense herum.

      Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()

      ErfinderDesRades schrieb:

      Was ein schlimmes FehlDesign ist
      Ich halte das für ein Relikt aus der 16-Bit-DOS + Windows 3.1-Zeit, unter VB3 (!) war das auch schon so. Wohl eher ein Kompatibilitäts-was-auch-immer.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Hörte sich gut an, funktioniert bei mir jedsoch nicht. Ausblendung ist wirkungslos.
      Siehe beigefügtes Projekt.
      Dateien
      @us4711 War bei mir auch so.
      @ErfinderDesRades Da sind 2 Zeilen versechselt, das Attribut greift auf die Methode, nicht aber auf das Modul:

      VB.NET-Quellcode

      1. Public Module InvisibleExtensions
      2. <EditorBrowsable(EditorBrowsableState.Never)> _
      3. <Extension()> _
      4. Public Function StringExtension1(s As String) As String
      5. Return "InvisibleExtensions.StringExtension1"
      6. End Function
      7. End Module
      So sollte es gehen.
      Bilder
      • Extension.jpg

        14,41 kB, 252×263, 128 mal angesehen
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Das EditorBrowsable-Attribut blendet nur das aus, auf was es angewendet wird:
      Code

      VB.NET-Quellcode

      1. Module Module0
      2. <Extension()>
      3. Sub Ext0(Target As Integer)
      4. MessageBox.Show("Hallo")
      5. End Sub
      6. End Module
      7. <EditorBrowsable(EditorBrowsableState.Never)>
      8. Module Module1
      9. <Extension()>
      10. Sub Ext1(Target As Integer)
      11. MessageBox.Show("Hallo")
      12. End Sub
      13. End Module
      14. Module Module2
      15. <EditorBrowsable(EditorBrowsableState.Never)>
      16. <Extension()>
      17. Sub Ext2(Target As Integer)
      18. MessageBox.Show("Hallo")
      19. End Sub
      20. End Module
      21. <EditorBrowsable(EditorBrowsableState.Never)>
      22. Module Module3
      23. <EditorBrowsable(EditorBrowsableState.Never)>
      24. <Extension()>
      25. Sub Ext3(Target As Integer)
      26. MessageBox.Show("Hallo")
      27. End Sub
      28. End Module
      29. '...
      30. Dim A As Integer = 0
      31. A.Ext0() 'Ext0 sichtbar
      32. A.Ext1() 'Ext1 sichtbar
      33. A.Ext2() 'Ext2 nicht sichtbar
      34. A.Ext3() 'Ext3 nicht sichtbar
      35. Module0.Ext0(A) 'Module0 sichtbar, Ext0 sichtbar
      36. Module1.Ext1(A) 'Module1 nicht sichtbar, Ext1 sichtbar
      37. Module2.Ext2(A) 'Module2 sichtbar, Ext2 nicht sichtbar
      38. Module3.Ext3(A) 'Module3 nicht sichtbar, Ext3 nicht sichtbar

      Alle Methoden können trotzdem aufgerufen werden.
      Wenn man z.B. Module1 hinschreibt (Wird in Intellisense nicht angezeigt) und anschließend einen Punkt macht, bekommt man Ext1 trotzdem angezeigt.

      Also sollte man das Attribut immer auf das Modul, und nicht auf die Member anwenden.

      @ErfinderDesRades
      Vielen Dank für diesen hilfreichen Tipp.
      "Luckily luh... luckily it wasn't poi-"
      -- Brady in Wonderland, 23. Februar 2015, 1:56
      Desktop Pinner | ApplicationSettings | OnUtils

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Niko Ortner“ ()

      Und genaus diese Verhalten kann ich inb meinem Projekt als Anlage in Post#1 nicht erkennen.
      Ob das Modul nun mit dem Attribut dekoriert ist, oder nicht, die Extensions werden IMMER in der Intellisense vorgeschlagen.
      Komisch.
      Weil wenn ich dein Teil downloade, verhält es sich, wie von mir beschrieben: Wenn ich anfange zu schreiben

      VB.NET-Quellcode

      1. Dim s = StringE
      Dann schlägt IntelliSense nur StringExtension2 vor, nicht aber StringExtension1, denn StringExtension1 befindet sich im als hidden attributiertem Modul.

      Wird die Extension aber richtig als Extension genutzt, so schlägt IntelliSense natürlich beide Methoden vor, denn sind ja beides Extensions.

      VB.NET-Quellcode

      1. Dim s01 = "Bla".StringExtension1
      2. Dim s02 = "Bla".StringExtension2
      Und genau das StringExtension1-Verhalten will ich ja erreichen: IntelliSense soll StringExtension1 nur dann vorschlagen, wenn die Methode auch richtig als Extension genutzt wird.

      Nochmal zusammengefasst:

      VB.NET-Quellcode

      1. Dim s01 = "Bla".StringExtension1 'richtig verwendete Extension - intellisense-gestützt
      2. Dim s02 = "Bla".StringExtension2 'richtig verwendete Extension - intellisense-gestützt
      3. Dim s2 = StringExtension2("Bla") 'falsch verwendete Extension - intellisense-gestützt
      4. Dim s1 = StringExtension1("Bla") 'falsch verwendete Extension - nicht intellisense-gestützt, dank der Browsable.Never-Attributierung des Moduls

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „ErfinderDesRades“ ()

      @Gonger96 Es geht ja nicht darum zu verhindern, dass eine extension "falsch" benutzt wird. Es geht darum, dass die IntelliSense nicht mit Extensions zugespammt wird :D
      Ich Antworte nach bestem Wissen und Gewissen. Ich übernehme keine Garantie für die Richtigkeit oder Fehlerfreiheit meiner Texte.


      Ich konnte dir helfen?
      - Das ist schön :) Ich würde mich über ein "Hilfreich" freuen ^^
      Also ich halte es in so fern für nützlich, dass ich beim Tippen von anderen Funktionen nicht mit Extensions zu gespammt werde. Da ich die ja gar nicht immer brauche, sondern nur wenn ich mit dem erweiterten Objekt arbeite.
      Ich Antworte nach bestem Wissen und Gewissen. Ich übernehme keine Garantie für die Richtigkeit oder Fehlerfreiheit meiner Texte.


      Ich konnte dir helfen?
      - Das ist schön :) Ich würde mich über ein "Hilfreich" freuen ^^
      @Gonger96
      Dann halt ich's für Unfug

      Der Sinn von Extensions ist, den Typ zu erweitern, auf die man die Extension anwendet, und nicht, als global verfügbare Methode zu agieren.

      Zusatz zu meinem vorherigen Post:
      Bei mir scheint das jetzt nicht mehr wie gewollt zu funktionieren.
      Ausgehend von Module1 Ich kann die Extensions immer noch aufrufen, wenn ich sie von Hand hinschreibe, aber sie werden im Intellisense nicht angezeigt, wenn ich das schreibe:

      VB.NET-Quellcode

      1. Dim A As Integer = 0
      2. A.Ext1() 'Wird nicht im Intellisense angezeigt


      Wenn ich jedoch den Namen des Modules voll ausschreibe (das Modul wird wie erwartet nicht angezeigt), dann werden die Funktionen darin angezeigt.

      Genaueres muss ich erst testen und mein VisualStudio spinnt gerade wegen dem SP1.
      Sicher sagen kann ich jedoch, dass sich das Modul mit den Extensions in einer anderen Assembly befindet und ich auf diese per Pfad-Verweis verweise.
      "Luckily luh... luckily it wasn't poi-"
      -- Brady in Wonderland, 23. Februar 2015, 1:56
      Desktop Pinner | ApplicationSettings | OnUtils