Pergunta

VB.NET 2010, .NET 4

Tenho uma pergunta básica: tenho uma sub -rotina que encontrei em algum lugar on -line declarado assim:

Public Sub MyFunction(Of T As Control)(ByVal Control As T, ByVal Action As Action(Of T)) ...

Estou me perguntando sobre o (De t como controle) parte da declaração após o nome do sub. Vejo que T é usado posteriormente para especificar o tipo de controle e em ação (de t), mas por que é feito dessa maneira, em vez de apenas fazer:

Public Sub MyFunction(ByVal Control As Control, ByVal Action As Action(Of Control)) ...

O que essa parte depois do nome do submarino significa? Qual é seu propósito? Muito obrigado e desculpe pela minha ignorância.

Foi útil?

Solução

(De t) é um parâmetro de tipo genérico, adicionando como controle restringe o tipo de t para herdar do controle. Você pode escrever o método da segunda maneira, mas provavelmente acabaria tendo que lançar o controle para qualquer tipo herdado, dentro da expressão de Lambda na ação ou no corpo da função. Os genéricos permitem que você evite isso.

Por exemplo:

Sub Main()
    Dim form As New Form()

    Dim textBox As New TextBox
    Dim listBox As New ListBox

    MyFunction(textBox, Sub(c) c.Text = "Hello")
    MyFunction(listBox, Sub(c) c.Items.Add("Hello"))

    MyFunction2(textBox, Sub(c) c.Text = "Hello")
    MyFunction2(listBox, Sub(c) CType(c, ListBox).Items.Add("Hello"))


End Sub

Public Sub MyFunction(Of T As Control)(ByVal Control As T, ByVal Action As Action(Of T))
    Action(Control)
End Sub

Public Sub MyFunction2(ByVal Control As Control, ByVal Action As Action(Of Control))
    Action(Control)
End Sub

Não parece muito valioso em casos triviais, mas é inestimável para casos mais complexos.

Outras dicas

Esse é o VB.NET's Método genérico Sintaxe da declaração:

Um tipo genérico é um único elemento de programação que se adapta para executar a mesma funcionalidade para uma variedade de tipos de dados. Quando você define uma classe ou procedimento genérico, você não precisa definir uma versão separada para cada tipo de dados para o qual você pode executar essa funcionalidade.

Uma analogia é uma chave de fenda com cabeças removíveis. Você inspeciona o parafuso que precisa girar e selecionar a cabeça correta para esse parafuso (com fenda, cruzado, estrelado). Depois de inserir a cabeça correta na alça da chave de fenda, você desempenha exatamente a mesma função com a chave de fenda, a saber, girando o parafuso.

Como outros disseram, é um parâmetro genérico restrito. Mas ninguém ainda abordou esta parte da sua pergunta:

Por que é feito dessa maneira

A resposta está na ação. Se fossem declarados como controle, você não seria capaz de fazer algo assim, porque nem todos os controles têm uma propriedade .Text*:

MyFunction(MyTextBox, Function(t) t.Text = "new value" )

O corpo da função só precisa saber que está funcionando com algum tipo de controle, mas a ação (de t) que você passa para a função pode querer saber o tipo real do controle.

Sim, todos os controles têm uma propriedade .Text. Vamos fingir por um momento que alguns não

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top