Defaultinstances projektweit unterbinden

  • VB.NET

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

    Defaultinstances projektweit unterbinden

    Hi,

    ich würde gerne für das ganze Projekt die standardinstanzen der Formen unterbinden. Ich habe bereits etwas ähnliches erreichen können, indem ich die Sichtbarkeit des Konstruktors verändere.
    Gibt es aber irgendeine Einstellung, mit der man sie einfach komplett abschalten kann?

    nikeee
    Von meinem iPhone gesendet
    Hab mal einiges experimentiert, es aber nicht geschafft. Das scheint so eine blöde VB-Eigenschaft im Studio zu sein, die iwie nicht abschaltbar ist.
    Wenn Du das diszipliniert nicht schaffst, wirst Du wohl auf C# umsteigen müssen. :S
    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!
    @nikeee13: Ist das wirklich so schwer, die Standardinstanzen nicht zu verwenden?

    Wenn die Form nur Konstruktoren mit Parametern hat, können die Standardinstanzen nicht verwendet werden:

    VB.NET-Quellcode

    1. Public Class Form2
    2. Public Sub New(Nope As Boolean)
    3. InitializeComponent()
    4. End Sub
    5. End Class

    Ergibt bei Form2.Show() diese Fehlermeldung:
    Der Verweis auf einen nicht freigegebenen Member erfordert einen Objektverweis.


    Wenn Du das bei der Startform auch machst, dann kommt noch eine Fehlermeldung. Im Normalfall kommst Du zur Fehlerstelle, indem Du einen Doppeklick drauf machst. Sollte das nicht der Fall sein, musst Du die Datei "Application.Designer.vb" suchen. Im Projektmappenexplorer musst Du "Alle Dateien anzeigen", dann unter MyProject\Application.myapp\Application.Designer.vb.

    Da änderst Du die Zeile bei OnCreateMainForm() von Me.MainForm = Global.WindowsApplication1.Form1 auf Me.MainForm = New Form1(False) (bzw. was auch immer Du an den Konstruktor gibst).


    Edit: Hab noch was getestet. Es reicht, den einzigen Konstruktor ohne Parameter als Private zu deklarieren. Aber das heißt, man kann nicht einfach Me.MainForm = New Form1 hinschreiben.
    Eine Möglichkeit wäre, eine Art Singleton-Pattern zu verwenden:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Shared _Instance As Form1
    3. Public Shared ReadOnly Property Instance As Form1
    4. Get
    5. If _Instance Is Nothing Then
    6. _Instance = New Form1
    7. End If
    8. Return _Instance
    9. End Get
    10. End Property
    11. Private Sub New()
    12. InitializeComponent()
    13. End Sub
    14. End Class

    Und dann einfach Me.MainForm = Form1.Instance verwenden.

    Edit2: Ich finde das übrigens sehr gut, dass das mal angesprochen wird. Ich werde in Zukunft hier her verlinken, wenn es sich ergibt.
    "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“ ()

    Die Standardinstanz gibt es übrigens nur in einem Windowsforms-Projekt. Wenn du es also schaffst, bei einer Consolenanwendung die Console wegzubekommen, dann hast du auch keine Standardinstanz mehr (hab aber keine Ahnung, ob oder wie das geht).

    Niko Ortner schrieb:

    Ist das wirklich so schwer, die Standardinstanzen nicht zu verwenden?
    Nein, ist es nicht. Ich möchte es nur verbieten, so dass jeder andere, der den Code eventuell verändern würde, dies nicht machen kann.
    Außerdem ist das auch eine Performancesache. Ich weiß nicht, ob die Standardinstanz lazy initialisiert wird. Wenn nicht, läuft das sicherlich im statischen Konstruktor... und dann habe ich immer eine Instanz im Speicher, die ich nicht benötige und nur Rechenzeit verschwendet.

    Edit: Sieht wohl so aus, als würden sie lazy initialisiert:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Property SomeForm() As SomeForm
    2. Get
    3. Me.m_SomeForm = MyProject.MyForms.Create__Instance__(Of SomeForm)(Me.m_SomeForm)
    4. Return Me.m_SomeForm
    5. End Get
    6. Set(value As MainWindow)
    7. If value Is Me.m_SomeForm Then
    8. Return
    9. End If
    10. If value IsNot Nothing Then
    11. Throw New ArgumentException("Property can only be set to Nothing")
    12. End If
    13. Me.Dispose__Instance__(Of SomeForm)(Me.m_MainWindow )
    14. End Set
    15. End Property

    Instanziierung (Teil des App Frameworks):
    Spoiler anzeigen

    VB.NET-Quellcode

    1. <DebuggerHidden()>
    2. Private Shared Function Create__Instance__(Of T As{Form, New})(Instance As T) As T
    3. If Instance Is Nothing OrElse Instance.IsDisposed Then
    4. If MyProject.MyForms.m_FormBeingCreated IsNot Nothing Then
    5. If MyProject.MyForms.m_FormBeingCreated.ContainsKey(GetType(T)) Then
    6. Throw New InvalidOperationException(Utils.GetResourceString("WinForms_RecursiveFormCreate", New String(0)))
    7. End If
    8. Else
    9. MyProject.MyForms.m_FormBeingCreated = New Hashtable()
    10. End If
    11. MyProject.MyForms.m_FormBeingCreated.Add(GetType(T), Nothing)
    12. Try
    13. Try
    14. Return Activator.CreateInstance(Of T)()
    15. End Try
    16. Dim arg_74_0 As Object
    17. Dim expr_79 As TargetInvocationException = TryCast(arg_74_0, TargetInvocationException)
    18. Dim arg_96_0 As Integer
    19. If expr_79 Is Nothing Then
    20. arg_96_0 = 0
    21. Else
    22. Dim ex As TargetInvocationException = expr_79
    23. ProjectData.SetProjectError(expr_79)
    24. arg_96_0 = (If(((ex.InnerException IsNot Nothing) > False), 1, 0))
    25. End If
    26. endfilter(arg_96_0)
    27. Finally
    28. MyProject.MyForms.m_FormBeingCreated.Remove(GetType(T))
    29. End Try
    30. Return Instance
    31. End If
    32. Return Instance
    33. End Function


    FYI:
    Momentan mache ich es mit einem Singleton, der deinem Vorschlag ähnlich ist.

    Die Tatsache, dass ich Singletons statt Standardinstanzen verwenden kann, löst das Problem aber leider nicht. Wenn ich den Konstruktor auf Private/Protected stellen würde, könnte man ja keine neuen Instanzen außerhalb der Klasse erstellen. Beim Singleton wäre es ja egal. So einen habe ich aber nicht in allen Fällen.

    Artentus schrieb:

    Wenn du es also schaffst, bei einer Consolenanwendung die Console wegzubekommen, dann hast du auch keine Standardinstanz mehr (hab aber keine Ahnung, ob oder wie das geht).

    Ist das nicht bei jeder C#-WinForms-Anwendung so? Bei VB sorgt wohl das VB-Application-Framework für die Standardinstanzen. Dieses verwende ich aber zum Teil (z. B. für die SingleInstance-Option.. und ja, das könnte man auch selber machen; darum geht es aber hier nicht).
    Von meinem iPhone gesendet

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „nikeee13“ ()

    Probier mal das:

    renevo.com/blogs/dotnet/archiv…amespace-from-vb-net.aspx

    Ich glaub eher, dass die DefaultInstances mit My.Application.OpenForms zu tun haben. Also, entledige Dich dem/des NameSpace My und die DefaultInstances sind verschwunden. Ich habe es gerade probiert und es funktioniert. Jedoch mit ein paar unschönen Nebenwirkungen. Diese hab ich mir jetzt nicht genauer angeschaut. Vielleicht hilft es Dir.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    My komplett entfernen möchte ich nicht, da ich dann den Zugriff auf die Ressourcen und die Settings verliere. Außerdem verliere ich dann wohl auch das Application Framework.

    Aber ja, die scheinen im My-Namespace zu liegen. Sieht man daran, wenn man via Decompiler mal in Projektname.My.MyProject.MyForms schaut. Dort schlummern die Standardinstanzen.


    Edit:
    Ich habe mir mal die Parameter von vbc.exe anschaut. Habe dort nichts zu Standardinstanzen gefunden. Was ich dort aber gefunden habe, ist folgender Parameter:

    Quellcode

    1. /vbruntime[+|-|*] Kompilieren Sie mit oder ohne die Visual Basic-Standardlaufzeit.

    Hilft mir jetzt zwar auch nicht weiter, aber vielleicht bringt es Euch ja irgendwann mal was.
    Von meinem iPhone gesendet

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

    Im Grunde müsstest Du nur My.Application loswerden (denke ich). Ob das möglich ist, kein Plan. War ja nur ein Denkanstoss. Wenn Du nen Weg findest, nur My.Application in die Tonne zu treten, lass es mich wissen. Wäre daran auch interessiert.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Ich habe mal ein bisschen gegooglet. My.Settings ist laut diesen Thread nicht teil des Application Frameworks. Die das mit den Ressourcen aussieht, weiß ich nicht. Ich werde mal schauen, ob ich das so einfach migrieren kann. Habe da meine Zweifel.


    Edit:
    Ich habe nun mal das Application Framework deaktiviert. Die Defaultinstances sind nicht verschwunden. Wirklich schade.
    Von meinem iPhone gesendet

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

    nikeee13 schrieb:

    Die Defaultinstances sind nicht verschwunden.
    So hab ich auch angefangen zu experimentieren.
    Auch das Rausschmeißen des VB-Namespaces bringt nix, das ist wohl einfach eine (ggf. nicht abschaltbare) VB-Eigenschaft.
    Vielleicht lässt sich das in einer höheren Version vom Studio anschalten. :S
    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!
    @nikeee13: Um nochmal auf den privaten Konstruktor zurückzukommen: Wenn Du von Außerhalb einen Konstruktor mit Parametern verwendest, ist es sowieso kein Problem. Wenn Du allerdings auch Konstruktoren ohne Parameter hast, müsstest Du denen einen zusätzlichen Sinnlosen Parameter geben (wie in meinem Beispiel Nope As Boolean). Das ist zwar etwas unschön, aber wahrscheinlich leider die einzige Lösung in diesem Zusammenhang.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    @nikeee13:: Soll das eine Vorgabe für einen disziplinlosen Haufen besserwisserischer Programmierer-werden-woller werden?
    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!
    Nein, eigentlich möchte ich nur die Möglichkeit nehmen, sowas zu machen. Wenn es nicht geht - auch gut. Ich Perfektionist und Guideline-/Paradigmen-Fetischist und kann die Defaultinstances deshalb einfach nicht leiden.
    Von meinem iPhone gesendet
    Bei neueren Sachen verwende ich ohnehin C#, aber bei diesem Projekt hat mir jegliche Motivation gefehlt, es nach C# zu portieren - vorallem weil das mit extremen Aufwand verbunden ist.

    Aber wenn es nicht anders geht, hat sich der Thread wohl erledigt.
    Von meinem iPhone gesendet