Autor Beitrag
paul.-b
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26



BeitragVerfasst: Mo 14.12.09 09:59 
Hallo zusammen,

Ich möchte Objekte unterschiedlicher klasse übergeben, die aber alle die gleiche Methode besitzen (gleicher name, Parameter und rückgabewert aber versch. Implementierung)
Jetzt möchte ich diese Methode Aufrufen. Wie kann ich die Objekte "generisch" in einer Methode übergeben und diese gemeinsame Funktion dann aufrufen (egal welcher typ kommt)
Und nein, die Klassen erben von keiner gemeinsamen Klasse. Den Code kann ich übrigens auch nicht umschreiben, weil ich ihn nich besitze.

Dank und Gruß
Paul
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Mo 14.12.09 11:36 
Hallo Paul,

das spricht für ein Interface: Das definiert die Methode als Deklaration; jede Klasse bindet das Interface ein und definiert die Methode so, wie sie es braucht. Der "einheitliche" Aufruf erfolgt dann ungefähr so:
ausblenden C#-Quelltext
1:
2:
IMyMethod item = myClassInstance as IMyMethod;
item.MyMethod();

In der Praxis wird es natürlich etwas komplexer, aber vom Grundsatz geht es so.

Gruß Jürgen
paul.-b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26



BeitragVerfasst: Mo 14.12.09 12:32 
Ich weiß nicht ob ich das richtig verstanden habe.
Meine Klassen können generell kein interface erben, da ich den Code nicht besizte.

Ich glaube aber du meinst es anders...
Ist dann "myClassInstance" ein generischer typ? Weil bei mir sind die KLassen komplett verschieden und haben nur eine Methodendeklaration gleich.

thx
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Mo 14.12.09 13:30 
user profile iconpaul.-b hat folgendes geschrieben Zum zitierten Posting springen:
Ich weiß nicht ob ich das richtig verstanden habe.
Meine Klassen können generell kein interface erben, da ich den Code nicht besizte.

Dann habe ich dich falsch verstanden. Der Begriff "Meine Klassen" ließ mich vermuten, dass du Einfluss auf die Definition hast.

user profile iconpaul.-b hat folgendes geschrieben Zum zitierten Posting springen:
Ich glaube aber du meinst es anders...
Ist dann "myClassInstance" ein generischer typ?

Nein, es ist kein Typ, sondern es ist das, was der Name sagt: Mit kleinem Anfangsbuchstaben ist es eine Variable, und zwar eine Instanz (also ein konkretes Objekt) vom Typ MyClass, also einer bestimmten Klasse.

Unter diesen Umständen gibt es höchstens eine Lösung: Leite von jeder der gegebenen Klassen eine (eigene) Klasse ab, die das Interface benutzt. Ob es allerdings mit der schon vorhandenen Methode funktioniert, kann ich nicht sagen.

Gruß Jürgen
paul.-b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26



BeitragVerfasst: Mo 14.12.09 14:47 
hmm, dann hätte ich aber mein Ziel verfehlt, wenn ich jede ableiten würde. Dann kann ich die auch für jeden typ meine Funktion überladen und die Gemeinsame Methode dort aufrufen.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 14.12.09 14:55 
Was soll das denn für eine Methode sein die alle Klassen haben aber weder von einem gemeinsamen Vorfahren kommt noch aus einem Interface?
Und wenn dem so ist wer programmiert so was?
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mo 14.12.09 15:45 
Hallo!

Ich denke, Du hast noch die Wahl, es mit Reflection zu machen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
        public void CallMethod(object o)
        {
            var t = o.GetType();
            var m = t.GetMethod("MyMethod");
            if (m != null)
                m.Invoke(o, null);
        }

Das wäre für eine Methode "MyMethod", die keine Parameter. Es gibt von GetMethod aber auch eine Überladung, welche Methoden mit bestimmten Parametern findet.

Grüße
Christian

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 14.12.09 15:51 
@Christian: Den Ratschlag hätte ich gerne explizit verhindert. Zumindest solange bis klar ist das es keinen anderen Weg gibt. Man sollte nicht versuchen architektonischen Unsinn durch Reflection ~richtig~ aussehen zu lassen ;)
paul.-b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26



BeitragVerfasst: Mo 14.12.09 16:30 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Was soll das denn für eine Methode sein die alle Klassen haben aber weder von einem gemeinsamen Vorfahren kommt noch aus einem Interface?
Und wenn dem so ist wer programmiert so was?


Es gibt Controls von DevExpress, welche die Methode SaveLayoutToStream(Stream stream) implementiert haben.
Ich möchte Control-Objekt(-Referenz) an eine Methode übergeben, die dann SaveLayoutToStream aufruft und intern den Stream in der Datenbank abzuspeichern.
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mo 14.12.09 17:07 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
@Christian: Den Ratschlag hätte ich gerne explizit verhindert. Zumindest solange bis klar ist das es keinen anderen Weg gibt. Man sollte nicht versuchen architektonischen Unsinn durch Reflection ~richtig~ aussehen zu lassen ;)
Wenn man die Klassen selber nicht ändern kann, was er ja in seinem ersten Posting schon schrieb, hat man halt keine andere Wahl :nixweiss:

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 14.12.09 17:38 
Zitat:
Wenn man die Klassen selber nicht ändern kann, was er ja in seinem ersten Posting schon schrieb, hat man halt keine andere Wahl


Man hat immer die Wahl einen nicht generische Ansatz zu wählen. Darum hätte ich erst auf mehr Details gewartet um zu entscheiden ob eine generische Lösung überhaupt Sinn macht.

Zitat:
Es gibt Controls von DevExpress, welche die Methode SaveLayoutToStream(Stream stream) implementiert haben.


Wenn du mal eine funktionierende Lösung hast würde mich die interessieren. Es geht ja nur(verglichen mit der gesamt Menge von DevEx Controls) so um 6-7 Klassen die SaveLayoutToStream unterstützen und nicht alle (z.B. die RibbonQuickAccessToolbar) sind Controls.

Edit: bei der NavBar heißt die äquivalente Funktion nicht SaveLayoutToStream sondern nur SaveToStream.
paul.-b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26



BeitragVerfasst: Di 15.12.09 15:15 
Die NavBar kann der Endbenutzer nicht beeinflussen (AFAIK) somit muss ich da auch nichts wegsichern. Ich möchte das nur mit den Controls machen wo der Endbenutzer etwas in der Darstellung anpassen kann. Diese soll er sich auch speichern können (bei mir in der DB)

Paul

ps: Wenns nicht anders geht, werde ichs über die genannte Methode mit Reflection machen.
Stehe leider unter besonderm Zeitdruck, der mir nicht erlaubt viel auszuproobieren. Danke aber für die bisherige Hilfe!
paul.-b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26



BeitragVerfasst: Do 17.12.09 16:32 
Habs jetzt am laufen, sieht etwa so aus:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
        
private void IterateThrough()
        {

            foreach (System.Windows.Forms.Control einControl in LayoutReference.Controls)
            {
                if (einControl != null)
                {

                    if (einControl.GetType().ToString().Contains("Grid"))
                    {
                        var t = einControl.GetType();
                        var m = t.GetProperty("MainView");
                        

                        var k = m.GetValue(einControl, null);
                        CallMethod(k, "SaveLayoutToStream");
                    }
                }
            }
        }

        private void CallMethod(object o, String fktName)
        {
            //var u = (DevExpress.XtraGrid.Views.Grid.GridView) o;
            var t = o.GetType();

            Type[] Parameter = new Type[1];

            Parameter.SetValue(typeof(System.String), 0);

            object[] blub = { LayoutStream };
            var m = t.GetMethod(fktName, Parameter);
            if (m != null)
                m.Invoke(o, blub);

            LayoutStream.Seek(0, System.IO.SeekOrigin.Begin);
        }


Musste das so machen, weil eine GridView in GridContro.MainView drin ist.
Der Ansatz ist nicht sehr generisch aber dafür schneller. Ich werde alle SaveTo... Controls separat implementieren wenn ich sie einmal benötigen werde
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 17.12.09 19:29 
Das ist eine generische Lösung die genau bei einem Control funktioniert. Das hilft nicht wirklich.
Mach es lieber ganz simpel.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
private void IterateThrough()
{
    foreach (System.Windows.Forms.Control einControl in LayoutReference.Controls)
    {
        DevExpress.XtraGrid.GridControl grid = einControl as DevExpress.XtraGrid.GridControl;
        if (grid != null)
        {
            grid.MainView.SaveLayoutToStream(LayoutStream);
            LayoutStream.Seek(0, System.IO.SeekOrigin.Begin);
        }
    }
}
paul.-b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26



BeitragVerfasst: Fr 18.12.09 09:49 
Nö, so wird es nicht gehen. Ich habe ja auch buttons, labels und andere Controls im XtraLayout.
Ich kann jetzt nicht alle als Gridcontrol casten. Nur eben die Controls, die ein GridControl sind.
So wie ichs gemacht hab, kann ich mit "Contains("AndereLayoutControls")" andere Controls, welche die SaveLayoutX sachen unterstützen auch aufrufen.

Wenn die GridView direkt in der Control Collection sein würde, könnte ich immer auf die Existenz der SaveLayoutX prüfen und entscprechende ausführen.
Geht aber nicht, da nicht alle sichtbaren Controls direkt im XtraLayout Control Collection drin sind.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 18.12.09 11:25 
Zitat:
Ich kann jetzt nicht alle als Gridcontrol casten. Nur eben die Controls, die ein GridControl sind.


Bei cast via as werden alle Controls die nicht dem angefragten Typ entsprechen zu null, darum der Test auf null dahinter. Alle nicht GridControls fallen also frühzeitig raus.
paul.-b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26



BeitragVerfasst: Fr 18.12.09 14:21 
Das wusste ich nicht. Dankeschön, ich werds mal so probieren!