The PIT
Röster från ITM-koncernen.

Partial class, partial structure

September 9, 2008 09:44 by Stefan Karlsson

De flesta vet väl att listboxarnas (och comboboxarnas) items är av typen object i .Net. Ofta hämtar jag data från en webservice och får t.ex ett dataset med en produkttabell i och vill därefter fylla en listbox med alla produkter i tabellen.

Det som visas i listrutan är det man får fram om man kör .ToString() på objektet. I de flesta fall, t.ex. om man har en struktur eller tabell från ett dataset så är det namnet på objekttypen man får fram om man kör ToString() på objektet, alltså fungerar det inte direkt att putta in detta.

Om man t.ex. skapar en struktur och använder denna för att fylla en listruta:

Public Class Form1     
  Public Structure Customer         
    Public CustomerID As Integer         
    Public FirstName As String         
    Public LastName As String     
  End Structure    
  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load         
    Dim item As New Customer         
    item.CustomerID = 0         
    item.FirstName = "Stefan"         
    item.LastName = "Karlsson"        
    ListBox1.Items.Add(item)     
  End Sub 
End Class

Så blir resultatet detta, inte precis vad man ville ha:

image

I strukturfallet så är detta inget problem, man overridar bara ToString() med en egen ToString() så kan man putta in vad man vill:

Public Structure Customer         
  Public CustomerID As Integer         
  Public FirstName As String         
  Public LastName As String         
  Public Overrides Function ToString() As String             
    Return Me.FirstName & " " & Me.LastName         
  End Function 
End Structure

På så vis så visar listrutan snällt det man vill:

image

Men om strukturen kommer från en klass du inte kan påverka? Låt säga att vi har en klass vi inte har möjlighet att ändra i. clsCustomer heter den och den har en funktion som heter GetCustomers som returnerar en lista av kunder av typen Customer (strukturen vi hade ovan).

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load         
  Dim CustomerClass As New clsCustomer         
  ListBox1.DataSource = CustomerClass.GetCustomer 'returnerar en List(Of Customer) 
End Sub

I ovanstående fall så har vi inte möjlighet att gå in i koden och overridea ToString. Det går inte heller att använda Extensions för att lägga till ToString på den befintliga strukturen då Extensions inte tillåter att man ändrar i befintligt gränssnitt, bara utökar den.

Det är här man kan använda magin av partial  klasser och partial structures

Genom att definiera upp en partial klass av typen clsCustomer och sedan inuti den definiera upp en partial struktur av typen Customer så kan vi overrida strukturens ToString() och få den att bete sig som vi vill:

Public Class Form1    
  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load         
    Dim CustomerClass As New clsCustomer         
    ListBox1.DataSource = CustomerClass.GetCustomer 'returnerar en List(Of Customer)     
  End Sub 
End Class
Partial Class clsCustomer     
  Partial Structure Customer         
    Public Overrides Function ToString() As String             
      Return Me.FirstName & " " & Me.LastName         
    End Function     
  End Structure 
End Class

När man skriver partialklassen i editorn så får man intellisense på vilka klasser man kan arbeta med, när man sedan skriver Partial Structure så får man upp de befintliga strukturerna i clsCustomer så det är lätt att koda på det här viset.

Det vi gjort nu är att vi hookat in på en befintlig klass, och befintlig struktur och overrideat ToString på strukturen, vilket gör att listboxen kommer att visa det vi vill.

image

Detta är även praktiskt om man har objekt som inte innehåller det man vill, t.ex. så hade ju customer-objektet FirstName och LastName, men vi ville ju att listrutan skulle innehålla fulständigt namn, det fanns inte med i objektet. På samma sätt skulle man kunna lägga på summeringar osv i orderobjekt m.m.

Om man arbetar i VS2008 så har man möjlighet att använda Extensions för att t.ex. utöka ett objekt med en summeringsfunktion och om man tänker efter lite så är Extensions ihop med Partial ruggigt starka verktyg som går att använda dagligen på många ställen för att underlätta implementation av externa objekt (och mycket annat också så klart).