Laden...

Test ob Object Methode exportiert

Erstellt von nba vor 19 Jahren Letzter Beitrag vor 19 Jahren 3.956 Views
N
nba Themenstarter:in
24 Beiträge seit 2005
vor 19 Jahren
Test ob Object Methode exportiert

Hallo,
ich möchte bei einem Object vom Type "object" feststellen, on die Methode
Focus(); implementiert ist. Zur Laufzeit natürlich.

Beispiel:


 public void MyFunction(object sender, string message)
 {
   /// tue irgendwas

   if (sender.Equals(null))
   {
     return;
   }

   if ("Focus(); ist implemetiert")
   {
     sender.Focus();
   }
 }
 

Möglich wäre über GetType(); den Type zu erfragen und eine Liste mit Typen
vorzuhalten. Das ist aber sehr unelegant.

Hat jemand eine Idee?

Gruß nba

Gruß nba
Webverzeichnis

P
939 Beiträge seit 2003
vor 19 Jahren

Mit dem Type-Objekt aus GetType() können definierte Methoden abgefragt werden. Nennt sich Reflection.

MSDN: Type.GetMethod Method

Gruss
Pulpapex

S
127 Beiträge seit 2004
vor 19 Jahren

du redest bestimmt von Form´s oder ???

Mach dir einfach die Vererbung zu nutze und teste ob das Objekt die Basisklasse sein kann, wo "Focus" implementiert ist.
Wenn das Objekt das nicht sein kann dann bekommst du eine Exception die du ja abfangen kannst. Und schon weißt du ob das Objekt diese Funktion hat oder halt nicht.

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo nba,

mal unabhängig von der allgemeinen Lösung von Pulpapex: Focus wird doch nur von der Control-Klasse eingeführt und ist entsprechend in den Unterklassen vorhanden. Der Test sender.GetType ().IsSubclassOf (typeof (Control)) ist also in deinem Fall vermutlich gleichbedeutend mit der Frage, ob Focus implementiert ist.

herbivore

N
nba Themenstarter:in
24 Beiträge seit 2005
vor 19 Jahren

Hallo,
euch allen Danke für die raschen Antworten.
Ich habe den Vorschlag von Pulpapex kurz implementiert und es funktioniert
ausgezeichnet. Die anderen Vorschläge werde ich morgen mal testen um zu
sehen ob es noch etwas eleganter geht.

Der Code sieht zZ so aus:


if (sender.Equals(null))
{
    return;
}

try
{
    if (!sender.GetType().GetMethod("Focus").Equals(null))
    {
        sender.Focus();
    }
}
catch (Exception ex)
{
    ///
}
 

Gruß nba
Webverzeichnis

P
939 Beiträge seit 2003
vor 19 Jahren

Mit Equals(null) vergleichen geht nicht. Der Equals-Vergleich würde entweder false zurückliefern oder eine NullReferenceException auslösen. Deshalb mit == vergleichen.

Wenn es wirklich um die Controls.Focus-Methode geht (so wie es aussieht), ist es besser auf die Control-Klasse zu testen, so wie schon von suny und herbivore vorgeschlagen.

// So
if(sender is Control) {
  Control c = (Control)sender;
  c.Focus();
}

// Oder so
Control c = sender as Control;
if(c != null) {
  c.Focus();
}
X
2.051 Beiträge seit 2004
vor 19 Jahren

Original von nba

  
if (sender.Equals(null))  
{  
    return;  
}  
  
try  
{  
    if (!sender.GetType().GetMethod("Focus").Equals(null))  
    {  
        sender.Focus();  
    }  
}  
catch (Exception ex)  
{  
    ///  
}  
   

*ROFL*

Wofür brauchst du diese prüfung überhaupt, wenn du bereits zur kompilierzeit das weißt?? 8o 8o

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo nba,

was ich nicht verstehe ist, wie sich


sender.Focus();

übersetzen lassen soll, wenn sender von einem Typ ist, von dem du nicht weiß, ob er Focus implementiert. Weiter oben ist sender ja auch von Typ Object. Das würde zu einem Compiler-Fehler führen.

herbivore

S
127 Beiträge seit 2004
vor 19 Jahren

@Xqgene
Hier wird geprüft ob der Sender das kann, es kann ja sein das eine Klasse das Ereignis auslöst die nicht die Methode unterstützt. Und somit muss man zur Laufzeit prüfen ob man die Methode ansprechen kann oder nicht.

@herbivore:
nein da sollte kein Compiler Fehler kommen, da das Objekt ja die Methode bereit stellen kann, aber nich muss. Das ist das Problem von Late-Binding, das der Compiler hier keine Fehler entdeckt.

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo suny,

LateBinding (in C#) entscheidet nur, welche der (überschriebenen) Methoden aufgerufen wird, aber durch die statische Typüberprüfung zur Compile-Zeit ist sichergestellt, dass mindestens eine der (überschriebenen) Methoden existiert. Wenn das nicht sichergestellt ist, gibt es eben einen Compiler-Fehler.

herbivore

X
2.051 Beiträge seit 2004
vor 19 Jahren

@suny: weißt du überhaupt, wovon du sprichst?

S
127 Beiträge seit 2004
vor 19 Jahren

@herbivore:
Ok ich bin mir da in C# nicht so ganz sicher, und habe es mal ausprobiert.


class Test
{
 [STAThread]
 static void Main(string[] args)
 {
  Object myVariable = new Object();
  myVariable = new myClass();
  myVariable.myMethode(); // liefert einen Compilerfehler
  ((myClass) myVariable).myMethode(); // geht
 }
}

class myClass : Object
{
 public void myMethode()
{
 Console.WriteLine("myMethode");
 }
}

Entschuldigung das ich da was falsches geschrieben habe, ich kenne das Late-Binding Konzept von C/C++. Und ich der Meinung bin das es keine schöne Art zu Programmieren ist. Deshalb verwende ich es nicht so gerne.

@Xqgene:
Ja weiß ich, warum ???

P
939 Beiträge seit 2003
vor 19 Jahren

Late-Binding ist ein Grundkonzept in jeder objekt-orientierten Runtime, Stichwort virtuelle Methoden. Du verwendest es ständig, ohne es zu merken.

X
2.051 Beiträge seit 2004
vor 19 Jahren

@suny
bei deinem bsp. ist das problem, nicht dass es die myMethode nicht gibt, sondern dass es beim casten fehler auftretten kann. sieh dazu beitrag von Pulpapex.

das hat nix mit später bindung (wie du sie meinst) zu tun.

in dem bsp. weiß der kompiler bereits, ob ne methode existiert oder nicht.

N
nba Themenstarter:in
24 Beiträge seit 2005
vor 19 Jahren

Hallo,
danke für die weiteren Antworten bis auf den ROFL, der offensichtlich nicht verstanden
hat wozu ein Forum gut ist. Ein Codeansatz zu seinerm Kommentar wäre sinnvoll
oder er sollte genaueres fragen.

Weiter,

sender.Focus();

ist wie richtig bemerkt nicht kompilierbar,
war wohl etwas spät gestern.

Der Code ist mit den neuen Hinweisen ist nun wie folgt und kompiliert wunderbar.

if(sender is Control)
{
        ((Control)sender).Focus();
}

Danke.

Gruß nba
Webverzeichnis

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo suny,

sorry, aber auch C und C++ haben eine statische Typprüfung. Für C++ gilt in Bezug auf Late-Binding daher genau das gleiche wie für C# => Compiler-Fehler. In C gibt es kein Late-Binding, aber auch da würde der Aufruf einer nicht existierenden Funktionen einen Compiler-Fehler verursachen.

herbivore

X
2.051 Beiträge seit 2004
vor 19 Jahren

Original von nba
Hallo,
danke für die weiteren Antworten bis auf den ROFL, der offensichtlich nicht verstanden
hat wozu ein Forum gut ist.

sei mir nicht böse. ich fand den code einfach lüstig. sollte ich dich beleidigt haben, dann entschuldige ich mich dafür.

N
nba Themenstarter:in
24 Beiträge seit 2005
vor 19 Jahren

Hi,
ist nicht wirklich ein Problem.

Bei der Methode handelt es sich um eine globale Fehlerbehandlung für eine
Application.
Wird ein Fehler von einem (Control) ausgelöst, so möchte ich das
Control Fokusieren, wird der Fehler nicht von einem (Control) ausgelöst, reicht
die Meldung, eine Fokusierung ist nicht möglich.

Gruß nba
Webverzeichnis

1.373 Beiträge seit 2004
vor 19 Jahren

Am elegantesten ist immer noch die Lösung von Pulpaplex:


Control c = sender as Control;
if(c != null) {
  c.Focus();
}

Schöner geht es echt nicht1

MfG VizOne, der den as Operator liebt 😁

N
nba Themenstarter:in
24 Beiträge seit 2005
vor 19 Jahren

Hi VizOne,
könntest du dir eine Sekunde Zeit nehmen und die Vorteile, gerne auch Performance
o.Ä. von


Control c = sender as Control;
if(c != null) {
  c.Focus();
}

bzw.


if(sender is Control)
{
        ((Control)sender).Focus();
}

nennen ?

Gruß nba
Webverzeichnis

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo nba,

einen Unterschied sehe ich nur, wenn 'sender' ein echter Ausdruck und nicht nur eine Variable ist. In diesem Fall würde der Ausdruck im zweiten Beispiel zweimal ausgewertet werden und im ersten Beispiel nur einmal. Das ist insbesondere dann relevant, wenn die Auswertung je nach Zeitpunkt bzw. Zustand zu unterschiedlichen Ergebnissen führen kann.

Von der Lesbarkeit finde ich jedoch das zweite Beispiel angenehmer (vor allem, wenn man sich noch die extra Zeile für die öffnene Klammer spart 🙂

HTH

herbivore

1.373 Beiträge seit 2004
vor 19 Jahren

Genaugenommen gibt es einen winzigen performancevorteil für as, weil hier der Typ des zu castenden objects nur einmal festgestellt werden muss. Bei is + cast passiert das zweimal (einmal beim is, einmal beim cast). Aber das ist wohl nicht so dramatisch.
Ich mag as auch deshalb, weil man da leichter nach suchen kann als nach einem cast. Naja, so groß sind die Unterschiede nicht.

Bei genauerer Betrachtung ist die Version mit is tatsächlich lesbarer, weil sie klarer darstellt, was der Autor vorhat. Wie wär's also mit einer Kombination?


if(sender is Control) {
  (sender as Control).Focus();
}

Dann hat man wenigstens nicht diesen unschönen C-Style-Cast.

MfG VizOne

N
nba Themenstarter:in
24 Beiträge seit 2005
vor 19 Jahren

Hi,
habe das ganze nochmal geändert in den Vorschlag von VizOne


if(sender is Control)
{
        (sender as Control).Focus();
}

den C/c++ Typecast gewöhne ich mir gerne ab, die extra Zeile f. d. Klammer
muß aber sein 😉

Danke euch

Gruß nba
Webverzeichnis

1.373 Beiträge seit 2004
vor 19 Jahren

Diskussion über code-layout abgetrennt zu Code layout

(tadaa, meine erste Aktion als Moderator 😄)

MfG VizOne