Toon posts:

[vb.net] Option Strict fouten

Pagina: 1
Acties:

Verwijderd

Topicstarter
Option Strict is erg strict zoals ik heb ondervonden. Voordat ik begon aan mijn timer project heb ik onder Tools>Options>VBDefaults Option Strict aangezet. Deze settings worden volgens mij meegegeven met elk nieuw gestart project, zo ook mijn timer project.

Ik heb geen idee hoe ik de Option Strict moet uitzetten nadat het al is opgenomen in het project. Dit zou ik wel graag willen weten.

Nu mijn probleem: Ik krijg een fout indien ik de volgende code gebruik met Option Strict aan. De error zit in het 'form1' gedeelte onderaan.

Form load:

code:
1
        Dim MyTimer As New CustomTimer



CustomTimer Class *eigen class*:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Public Class CustomTimer
    'timer values
    Private HourLeft As Integer
    Private MinuteLeft As Integer
    Private SecondLeft As Integer


    Public Sub New()
        'initialize countdown values and call SetTimer to set the timer to default values
        HourLeft = 0
        MinuteLeft = 0
        SecondLeft = 0

        Call SetTimer()

    End Sub
    Public Sub SetTimer()

        'Creat displayvariables (as strings for length property use) 
        'and add zeros if necessary for correct display
        Dim HourLeftString As String = HourLeft.ToString
        Dim MinuteLeftString As String = MinuteLeft.ToString
        Dim SecondLeftString As String = SecondLeft.ToString

        If HourLeftString.Length = 1 Then HourLeftString = "0" & HourLeftString
        If MinuteLeftString.Length = 1 Then MinuteLeftString = "0" & MinuteLeftString
        If SecondLeftString.Length = 1 Then SecondLeftString = "0" & SecondLeftString

        'Set timer countdown window
        Form1.lblTimerMain.Text = HourLeftString & " : " & MinuteLeftString & " : " & SecondLeftString

    End Sub
End Class



En een lblTimerMain label op form1 toevoegen. Waarom geeft dit een error met option strict aan?

Volgens mij heeft het met Option Strict te maken iig. Dit is de exception:

An error occurred creating the form. See Exception.InnerException for details. The error is: The form referred to itself during construction from a default instance, which led to infinite recursion. Within the Form's constructor refer to the form using 'Me.'

[ Voor 8% gewijzigd door Verwijderd op 14-09-2006 22:44 ]


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 13-02 20:06

Gerco

Professional Newbie

Verwijderd schreef op donderdag 14 september 2006 @ 22:41:
An error occurred creating the form. See Exception.InnerException for details. The error is: The form referred to itself during construction from a default instance, which led to infinite recursion. Within the Form's constructor refer to the form using 'Me.'
Dit lijkt me nogal triviaal eigenlijk, en het heeft niets met Option Strict te maken. Je code is gewoon fout en de foutmelding is glashelder. Dit is wat er gebeurt:

1. Je maakt een defaut instance van Form1:
Visual Basic .NET:
1
Form1.Show ' Dit maakt een default instance van Form1 als die nog niet bestaat


2. Dat form maakt in zijn constructor een timer object:
Visual Basic .NET:
1
        Dim MyTimer As New CustomTimer


3. Die timer maakt vervolgens weer een default instance van Form1:
Visual Basic .NET:
1
        Form1.lblTimerMain.Text = HourLeftString & " : " & MinuteLeftString & " : " & SecondLeftString

Form1 is hier nog niet klaar met constructen en bestaat dus nog niet. De reference naar Form1 zorgt ervoor dat de constructor van Form1 weer word aangeroepen. Dit is effectief een "Goto step 2".

De oplossing is dus om de instance van Form1 mee te geven aan de timer wanneer je die construct:
Visual Basic .NET:
1
2
  Dim MyTimer As CustomTimer
  MyTimer = new CustomTimer(Me)

En dan in de customtimer de reference naar Form1 gebruiken ipv de naam Form1. Dit heeft overigens misschien ook zo zijn problemen bij gebruik van meerdere threads, maar hoe dat op te lossen laat ik graag aan anderen over.

Het is overigens altijd een goed idee om "Option Strict" aan te hebben. Als je een fout niet ziet, betekent dat nog niet dat je er geen last van gaat krijgen. Zonder Option strict zou je een oneindige loop krijgen in je code en had je moeten raden naar de oorzaak. Nu kreeg je die op een presenteerblaadje.

[ Voor 8% gewijzigd door Gerco op 14-09-2006 22:59 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Topicstarter
Bedankt, Ik zie nu wat er gebeurt.

Ik had Dim MyTimer As New CustomTimer niet in de form load staan, maar erboven (begin van de form1 class. Voordat dit form1 was gecreeerd werd al data in het label gestopt.

Door Dim MyTimer As Customtimer daar neer te zetten en MyTimer = New CustomTimer() in de form load los ik dit op. Een beetje stom dat ik dit niet heb gezien.

Ik snap trouwens niet wat je wat je bedoelt met het Me tussen haakjes, wat voor doel heeft dit?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
De "(me)" is een parameter voor de constructor. Je geeft jezelf ("me" dus) mee aan het object. Het "me" keyword is gewoon de huidige instance van een classe (in dit geval dus het form), maar dat had je ook gevonden als je op F1 had gemept:
Provides a way to refer to the specific instance of a class or structure in which the code is currently executing.

The Me keyword behaves like either an object variable or a structure variable referring to the current instance. Using Me is particularly useful for passing information about the currently executing instance of a class or structure to a procedure in another class, structure, or module. For example, suppose you have the following procedure in a module.
Me is vergelijkbaar met / hetzelfde als "this" in (o.a.) C#

[ Voor 69% gewijzigd door RobIII op 15-09-2006 00:08 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Verwijderd

Topicstarter
Ok, bedankt.

Weet iemand ook hoe ik Option Strict en Option Explict kan wijzigen tijdens een project. Ik weet hoe ik de defaults moet aanpassen? Maar volgens bij een wijziging van deze waarden dit niet doorgevoerd in het huidige project. Of is dit wel het geval?

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 13-02 20:06

Gerco

Professional Newbie

Waarschijnlijk in de eerste twee regels van je file (moet je misschien wel wat code uitklappen of unhiden) staat:
Visual Basic .NET:
1
2
Option Explicit
Option Strict


Als je die weghaalt, staan ze dus uit. Nogmaals: Deze opties uitzetten is een lapmiddel "at best", je code is dan nog steeds fout en je gaat wazige fouten krijgen in de toekomst. Het eerste wat je gevraagd word als je hier een antwoord zoekt is dan ook om die twee weer aan te zetten :)

Velen (waaronder ik) zijn van mening dat deze geen optie moeten zijn, dat zijn ze in alle andere serieuze strong typed talen ook niet en dat ze dat in VB.NET wel zijn is bijzonder kwalijk. Het zorgt (net als bij VB6) voor een slechte reputatie van de taal door het vele gepruts wat ermee plaatsvind.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Topicstarter
Ik snap je standpunt, maar option Strict geeft soms rare problemen.

Bijvoorbeeld: Ik ben bezig aan een function in mijn Class. Deze is nog niet compleet, en option Strict geeft veel lijntjes. Ik laat het even rusten en werk wat aan de UI. Indien ik op F5 druk om het resultaat van het UI werk te bekijken, worden mijn UI wijzigingen niet doorgevoerd. Indien ik de function uitcomment geeft het geen probleem, de wijzigingen worden in dat geval wel doorgevoerd.

Option Strict is een prima tool, maar wel als je het makkelijk aan het uit kan schakelen via de regel boven je class. Op deze manier belemmert 'foute' code in een deel van je programma het werk aan een ander deel van het programma niet. De vb defaults worden ergens anders opgeslagen aangezien ze niet te vinden zijn in mijn General Declarations.

Ik heb het kunnen oplossen door Option Strict Off toe te voegen aan de General Declarations. Het werkt wel, maar toe zou ik graag de vb defaults voor dit project alsnog veranderen. Weet iemand waar ik dit kan doen?

edit: Gevonden via help :)

Verwijderd

Topicstarter
Ik heb nog een probleem.

Mijn customClass (CustomTimer)

code:
1
2
3
4
5
6
7
8
9
10
Public Class CustomTimer

    Inherits System.Timers.Timer

...


Private Sub CustomTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Me.Elapsed
        Call TimerCountdown() ' sub in customclass
    End Sub


form1:
code:
1
2
Dim MyTimer As CustomTimer
MyTimer = New CustomTimer


In een buttonclick event van form1.

code:
1
2
        MyTimer.Interval = 1000
        MyTimer.Start()



Er gebeurt alleen niet zoveel na het uitvoeren van MyTimer.Start(). Heeft iemand een idee? Alles werkt wel goed indien ik een System.Timers.TImer control toevoeg.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Wat dacht je van de event handler te koppelen aan je nieuwe time instance 'MyTimer' ? Je bind nu je event handler aan Me.Elapsed, maar die doet niets met je eigen timer instance MyTimer.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

Topicstarter
Ik had al geprobeerd om er > handles MyTimer.Elapsed < van te maken. Maar in dat geval krijg ik een blauw lijntje met 'Handles clause requires a WithEvents variable defined in the containing type or one of it's base types.'. INtellisense geeft ook enkel de opties 'me', 'myclass' en 'mybase'.

Dat werkt dus niet.

Verwijderd

Topicstarter
Heeft iemand een idee?

De Private Sub CustomTimer_Elapsed moet toch in de class staan, of moet deze in form1 worden gezet? In dat geval krijg ik overigens nog steeds hetzelfde blauwe lijntje.

[ Voor 79% gewijzigd door Verwijderd op 18-09-2006 19:59 ]


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 10:54

gorgi_19

Kruimeltjes zijn weer op :9

Verwijderd schreef op maandag 18 september 2006 @ 15:43:
Ik had al geprobeerd om er > handles MyTimer.Elapsed < van te maken. Maar in dat geval krijg ik een blauw lijntje met 'Handles clause requires a WithEvents variable defined in the containing type or one of it's base types.'. INtellisense geeft ook enkel de opties 'me', 'myclass' en 'mybase'.

Dat werkt dus niet.
En heb je al uitgevoerd wat die foutmelding zegt?

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
Ik snap de foutmelding niet..

  • compufreak88
  • Registratie: November 2001
  • Laatst online: 02-05-2025
Je kunt het op twee manieren doen:

Met WithEvents:
Dan moet je de declaratie van je class als volgt doen:

dim withevents class as new class

Dit moet je dan wel bij je declerations doen, want anders is er geen reference.

Andere manier is om zelf een functie te maken, en dan de een handler toevoegen naar die functie.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
In de foutmelding wordt gemeld dat je het op kan lossen met "WithEvents" dan is het toch niet zo moeilijk om in de help op te zoeken hoe "WithEvents" werkt?

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 13-02 21:26

Creepy

Tactical Espionage Splatterer

En daarnaast: kicken binnen 24 uur is echt niet nodig. Als er een paar uur geen post is geweest wil dat niet zeggen dat niemand meer je topic zal zien ;)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
compufreak88 schreef op maandag 18 september 2006 @ 21:38:
Je kunt het op twee manieren doen:

Met WithEvents:
Dan moet je de declaratie van je class als volgt doen:

dim withevents class as new class

Dit moet je dan wel bij je declerations doen, want anders is er geen reference.

Andere manier is om zelf een functie te maken, en dan de een handler toevoegen naar die functie.
Ik heb geprobeert met het WithEvents te werken, maar het MyTimer object wordt niet geaccepteerd bij het handles deel achter de method. Dit is mijn code met een timepicker control (gezet op tijd input), een button (btnStart) en een label (lblCountdown):

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Option Strict On

Public Class Form1

    Dim WithEvents MyTimer As CustomTimer
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        MyTimer = New CustomTimer()

    End Sub

    
    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
        MyTimer.HourLeft = Convert.ToInt32(TimePicker.Value.Hour)
        MyTimer.MinuteLeft = Convert.ToInt32(TimePicker.Value.Minute)
        MyTimer.SecondLeft = Convert.ToInt32(TimePicker.Value.Second)

        Call MyTimer.SetTimerLabel()

        MyTimer.Interval = 1000
        MyTimer.Start()
      
    End Sub
End Class


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
Option Strict On

Public Class CustomTimer

    Inherits System.Timers.Timer

    'timer values
    Private m_HourLeft As Integer
    Private m_MinuteLeft As Integer
    Private m_SecondLeft As Integer


    Public Sub New()
        'initialize countdown values and call SetTimerLabel
        HourLeft = 0
        MinuteLeft = 0
        SecondLeft = 0

        Call SetTimerLabel()

    End Sub

    Public Property HourLeft() As Integer
        Get
            Return m_HourLeft
        End Get
        Set(ByVal value As Integer)
            m_HourLeft = value
        End Set
    End Property

    Public Property MinuteLeft() As Integer
        Get
            Return m_MinuteLeft
        End Get
        Set(ByVal value As Integer)
            m_MinuteLeft = value
        End Set
    End Property

    Public Property SecondLeft() As Integer
        Get
            Return m_SecondLeft
        End Get
        Set(ByVal value As Integer)
            m_SecondLeft = value
        End Set
    End Property


    Public Sub SetTimerLabel()

        'Create displayvariables (as strings) 
        'and add zeros if necessary for correct (double digit) display
        Dim HourLeftString As String = m_HourLeft.ToString
        Dim MinuteLeftString As String = m_MinuteLeft.ToString
        Dim SecondLeftString As String = m_SecondLeft.ToString

        If HourLeftString.Length = 1 Then HourLeftString = "0" & HourLeftString
        If MinuteLeftString.Length = 1 Then MinuteLeftString = "0" & MinuteLeftString
        If SecondLeftString.Length = 1 Then SecondLeftString = "0" & SecondLeftString

        'Set timer countdown window
        Form1.lblCountdown.Text = HourLeftString & " : " & MinuteLeftString & " : " & SecondLeftString

    End Sub

    Public Sub TimerCountdown()
        'for testing purposes, still incomplete...
        m_SecondLeft = m_SecondLeft - 1
        Call SetTimerLabel()

    End Sub

    Private Sub CustomTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Me.Elapsed
        Call TimerCountdown()
    End Sub
End Class

Verwijderd

Topicstarter
Heeft niemand een idee, met de suggesties kom ik er nog steeds niet uit.
Pagina: 1