xsharp.eu • Extensions
Page 1 of 1

Extensions

Posted: Thu Jan 30, 2020 10:24 am
by lagraf
In VO habe ich bei den internen Klassen öfter Methoden hinzugefügt, z.B:

Code: Select all

METHOD PostFocus() CLASS Control
    PostMessage( GetParent(SELF:Handle()) , WM_NextDlgCtl , DWORD( _CAST , SELF:Handle() ) , 1L )
    IF IsInstanceOf(SELF,#SingleLineEdit)
        PostMessage(SELF:Handle(), EM_SETSEL, 0, LONG(_CAST,SLen(RTrim(SELF:TextValue))))
        PostMessage(SELF:Handle(), EM_SCROLLCARET, 0, 0L )
    ELSEIF IsInstanceOf(SELF,#MultiLineEdit)
        PostMessage(SELF:Handle(), EM_SETSEL, 0, 0L )
        PostMessage(SELF:Handle(), EM_SCROLLCARET, 0, 0L )
    ENDIF
    RETURN NIL
In X# geht das ja nicht mehr, daher habe ich es mit Extensions versucht, damit ich die SLEs nicht von einer anderen Klasse ableiten muss:

Code: Select all

CLASS EditExtensions
METHOD PostFocus() 
    PostMessage( GetParent(SELF:Handle()) , WM_NextDlgCtl , DWORD( _CAST , SELF:Handle() ) , 1L )
    IF IsInstanceOf(SELF,#SingleLineEdit)
        PostMessage(SELF:Handle(), EM_SETSEL, 0, LONG(_CAST,SLen(RTrim(SELF:TextValue))))
        PostMessage(SELF:Handle(), EM_SCROLLCARET, 0, 0L )
    ELSEIF IsInstanceOf(SELF,#MultiLineEdit)
        PostMessage(SELF:Handle(), EM_SETSEL, 0, 0L )
        PostMessage(SELF:Handle(), EM_SCROLLCARET, 0, 0L )
    ENDIF
    RETURN NIL
END CLASS
Allerdings mag der Compiler den Zugriff auf SELF:Handle() und SELF:TextValue nicht. Kann man das lösen, ohne eine eigene Klasse MyEdit darüberzulegen und alle SLEs neu abzuleiten?

Extensions

Posted: Thu Jan 30, 2020 11:13 am
by wriedmann
Hallo Franz,
extension methods schreibt man anders:

Code: Select all

static method PostFocus( self oSLE as SingleLineEdit ) as void
dann kannst Du innerhalb der Methode mit

Code: Select all

PostMessage( oSLE:Handle() )
auf das SLE-Objekt zugreifen.
Aber Achtung: weil die Extension-Methode von außen an die Klasse drangeflanscht wird, hat sie keinen Zugriff auf Protects und sonstige Klassen-Interna.
Wolfgang

Extensions

Posted: Fri Jan 31, 2020 6:15 am
by lagraf
Hallo Wolfgang,
dann sind die Extensions eine Art primitive Vererbung, wo den Methoden als erster Parameter das Mutterobjekt mitgegeben wird. Geht das auch mit Access und Assign?
Franz

Extensions

Posted: Fri Jan 31, 2020 6:54 am
by wriedmann
Hallo Franz,
extension methods sind im Prinzip von außen drangeflanschte Methoden, weil eine Klasse für sich selber immer abgeschlossen ist. Sie kann zwar auf mehrere Quellcode-Dateien aufgeteilt werden, aber immer nur in einer Assembly definiert werden.
Das hat damit zu tun, dass sie anderes als in VO komplett zur Compile-Zeit definiert wird (in VO wird die Liste der Methoden einer Klasse beim Laden der Applikation/DLL erstellt).
Für Access/Assign geht das leider nicht - wäre auch nicht sehr sinnvoll, da der Zugriff auf Klassen-Interna nicht möglich ist (da von außen drangehängt).
Wolfgang

Extensions

Posted: Wed Apr 28, 2021 2:59 pm
by pemo18
Hallo Wolfgang,

Gut, dass Du mal so nebenbei die Schreibweise erwähnst, die ich in der X#-Hilfe nicht gefunden habe.

Ich habe vor kurzem eine Methode gebraucht, die aus einer generischen Liste eine DataTable macht. Dafür sind Extension Methods sehr praktisch.

Methode anbei.

Viele Grüße,
Peter

Class DataTableHelper

Static Method Convert2DataTable<T>(Self List as List<T>) As DataTable
Local ta := DataTable{} As DataTable
Local itemType := typeof(T) As Type
Local properties := TypeDescriptor.GetProperties(itemType) As PropertyDescriptorCollection
try
foreach propDesc As PropertyDescriptor in properties
ta:Columns:Add(DataColumn{propDesc:Name, propDesc:PropertyType})
next
foreach item As T in List
Local row := ta:NewRow() As DataRow
foreach propDesc As PropertyDescriptor in properties
row[propDesc:Name] := propDesc:GetValue(item)
next
ta:Rows:Add(row)
next
catch ex As SystemException
Console.WriteLine("!!! Fehler in Convert2DataTable (" + ex:Message + ") !!!")
end try

Return ta

End Class

Danach besitzt eine generische Liste automatisch eine Convert2DataTable-Methode:
Local DokListe := List<Dokument>{} As List<Dokument>
...
Local taDok = DokListe.Convert2DataTable() As DataTable

Das geht alles auch ohne Extension Method, aber der Code wird besser lesbar und man kann leichter Programmcode aus der C#-Welt übernehmen;)

Extensions

Posted: Wed Apr 28, 2021 3:07 pm
by wriedmann
Hallo Peter,

ja, extension methods haben schon was für sich.... in meiner BaseLib gibt es da jede Menge Methoden, die sich an die String-Klasse oder an die DateTime-Klasse dranhängen.
Und was Datenzugriff betrifft: mich hat es immer genervt, dass ich beim Zugriff auf DataRow.Inhalte oft casten muss, also gibt es bei mir auch entsprechende Anhängsel der DataRow-Klasse:

Code: Select all

public static method GetString( self oDataRow as DataRow, cFieldName as string ) as string
local oValue as object
local cReturn as string

cReturn := ""
oValue := oDataRow[cFieldName]
if oValue == DBNull.Value
  cReturn := ""
else
  cReturn := oValue:ToString()
endif
return cReturn
(Errorhandling habe ich der Einfachheit halber rausgenommen).
Wolfgang