• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

zephirus

Criar lista de funções

11 mensagens neste tópico

Olá,

Não sei se isto é possível de fazer. Deixo aqui um exemplo para melhor perceberem o meu programa.

Imaginem 2 funções:

Public Function funcao1(a as Integer, b as Integer, c as Integer) As Boolean
Public Function funcao2(a as Integer, b as Integer, c as Integer) As Boolean

Agora o código onde vou buscar as funções:

Select Case xpto1
   Case = True
      resfuncao1 = funcao1(a, b, c)
         If resfuncao1 = True Then
            Select case xpto2
               Case = True
                  resfuncao2 = funcao2(a, b, c)
                  If resfuncao2 = True Then
                     num = num + 1
                  End If
               Case = False
                  num = num + 1
            End Select
         End If
   Case = False
      Select Case xpto2
         Case = True
            resfuncao2 = funcao2(a, b, c)
            If resfuncao2 = True Then
               num = num + 1
            End If
         Case = False
            num = num + 1
      End Select
End Select

Resumidamente o código funciona da seguinte maneira:

1. Se xptoX for True eu corro a funcaoX

2. Verifico o resultado da funcaoX e se for True corro a funcaoX+1

Não me consigo explicar melhor mas basicamente é um procedimento em escada onde as funções que aqui a título de exemplo são apenas 2, podem ser dezenas no meu programa final.

A minha pergunta é se eu posso criar uma lista de funções para poder usar ciclos FOR, ou seja, é possível fazer isto:

Public listafuncoes As List(Of Label) = New List(Of Label)

listafuncoes.Add(funcao1)

listafuncoes.Add(funcao2)

E depois o meu código poderia ser qq coisa do género:

For i As Integer = 1 to 2
Select Case xpto(i)
   Case = True
      Select Case listafuncoes(i - 1)
         Case = True
            resfuncao(i-1) = funcao(i-1)(num0, num1, num2, num3, num4)
...
...

e por ai fora.

Provavelmente fui muito confuso. Qualquer dúvida, perguntem.

Obrigado desde já.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

De maneira mais simplificada:

Tenho estas duas funções:

Function funcao1(a As Integer, b As Integer) As Integer
   Return a + b
End Function

Function funcao2(a As Integer, b As Integer) As Integer
   Return a * b
End Function

E na minha MainForm tenho um label1 e um button1 e o seguinte código:

Sub Button1Click(sender As Object, e As EventArgs)
   Dim ans As Integer = funcao2(2, 3)
   label1.text = ans
End Sub

O que eu pretendia fazer era ir buscar a funcao2 mas como sendo funcao(2), ou seja com um index de modo a eu poder ir chamar N funções com menos código.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes fazer isso criando uma lista de delegates das tuas funções.

Depois só tens de usar o método Invoke. Em C# (já que não sei muito de VB, mas a lógica interna é igual), seria algo do tipo:

// Dás uma assinatura pro delegate que as tuas funções têm de respeitar
private delegate int Funcao(int x, int y);

// Presume-se que tens a funcao1, funcao2, funcao3 que respeitam a assinatura, tipo
private int funcao1(int x, int y) { return x + y; }
private int funcao2(int x, int y) { return x * y; }
private int funcao3(int x, int y) { return 2*x+y;}

// Depois crias a lista de funções, provavelmente no construtor do Form (acho que estavas a suar Form certo?)
List<Funcao> funcoes = new List<Funcao>();
funcoes.Add(new Funcao(funcao1));
funcoes.Add(new Funcao(funcao2));
funcoes.Add(new Funcao(funcao3));

// Depois para chamar uma determinada função (por exemplo a funcao2)
int r = (int) this.Invoke(this.funcoes[2], new object[] {2, 3});
// r terá o valor de 2 * 3, ou seja, 6

O código provavelmente ainda poderia estar melhor. Em vez de se adicionar função a função pra lista, provavelmente conseguiria-se arranjar uma maneira de gerar o nome da função (string) através de um ciclo. E depois através de Reflection ir buscar a função. Fica para trabalho de casa :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Parece-me que queres complicar. Porque não vais pelo método mais simples ?

Ex.:

    Enum Type
        opt1
        opt2
        opt3
    End Enum

    Private Function abc(ByVal a As Integer, ByVal b As Integer, ByVal c As Type) As Integer
        Select Case c
            Case Type.opt1
                Return a + b
            Case Type.opt2
                Return a * b
            Case Type.opt3
                Return a - b
            Case Else
                Return 0
        End Select
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Debug.Print(abc(1, 3, Type.opt1))
    End Sub

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É isso mesmo jpaulino. Já tinha implementado dessa maneira ontem. Fui um bocado parvo  :wallbash:

Obrigado

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
É isso mesmo jpaulino. Já tinha implementado dessa maneira ontem. Fui um bocado parvo

Ás vezes as coisas mais obvias não nos aparecem na altura e andamos à procura de soluções mais complicadas.

Acontece a todos! :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Aproveito ainda este tópico para colocar outra questão.

Imaginem a situação em que no load de uma form, eu crio um novo label:

Dim lbl1 As Label = New Label
lbl1.Name = "xpto"
lbl1.Text = "teste"
Me.Controls.Add(lbl1)

Até aqui tudo bem. O que eu prentedo agora é que ao clicar nesse label, me feche o programa, por exemplo. Ora, pensei que seria tão simples como isto:

Private Sub teste.click(ByVal sender As System.Object, ByVal e As System.EventArgs)
   Me.Close()
End Sub

Só que isto não funciona. Diz-me que o label "teste" não existe e eu entendo esta mensagem de erro pois o label ainda não foi criado. Como é que resolvo isto?

Obrigado

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tens de fazer o seguinte :

 

Private Sub LabelClick(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim lb As Label = CType(sender, Label)
        MessageBox.Show(String.Format("Click na label {0}", lb.Name))
        Me.Close()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim lbl1 As Label = New Label
        lbl1.Name = "Abc"
        lbl1.Text = "test"
        Controls.Add(lbl1)
        AddHandler lbl1.Click, AddressOf LabelClick
    End Sub

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O "AddHandler lbl1.Click" permite que esse comando esteja disponível certo?

Imagina que eu quero ir buscar uma propriedade desse label. Como é o "AddHandler" nesse caso? Será "AddHandler lbl1.text"?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não tenho a certeza se funciona com declarações locais (só testei em declarações globais com Public) mas podes tentar

Dim WithEvents lbl1 As New Label
lbl1.Name = "bla"
Me.Controls.Add(lbl1)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O AddHandler associa um evento a um objecto. Ou seja quando crias um evento num botão (por exemplo) ele automaticamente faz:

Private Sub Button1_Click(...) Handles Button1.Click ou seja quando o utilizador clica no botão irá correr este código.

Quando se adiciona controlos dinamicamente é necessário definir que evento irá ser disparado com que código. Daí utilizar-se o AddHander, para atribuir eventos ao objecto.

A segunda parte, o AddressOf, indicar que código irá ser corrido com aquele evento for disparado. No exemplo mostrei-te como ir buscar as propriedades do objecto através do Dim lb As Label = CType(sender, Label).

Não podes atribuir o handle a uma propriedade só um método/evento.

Para ir buscar o texto só precisas (e aproveitando o exemplo anterior) só precisas de fazer:

Dim lb As Label = CType(sender, Label)

Debug.Print(lb.Text)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora