Autor Beitrag
maxx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70



BeitragVerfasst: Sa 24.04.10 12:23 
hello,

mal wieder eine Frage.

Ich habe folgendes:

ausblenden 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:
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
   public partial class Form1 : Form
   {
      public Form1()
      {
         InitializeComponent();
      }

      private void button1_Click(object sender, EventArgs e)
      {
         Form2<X> form2 = new Form2<X>(new X());
         form2.Show();
      }
   }
   public class X
   {
      public void M()
      {
      }
   }
}


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
   public partial class Form2<TA> : Form
   {
      public Form2(TA a)
      {
         InitializeComponent();
         a.M(); <- PROBLEM! Kennt Methode M nicht!
      }
   }
}

Ich würde im Form2 gerne irgendwie mit Methoden von X arbeiten.
Geht das nicht??
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: Sa 24.04.10 12:33 
Du mußt der generischen Klasse sagen was dein generischer Parameter für Features beherrscht. Du solltest in der Hilfe mal das Where-Schlüsselwort nachschlagen.

Kurzfassung

ausblenden C#-Quelltext
1:
2:
3:
4:
public partial class Form2<TA> : Form where TA : X
{
  ....
}


So kann danach dein TA jede Ableitung von X darstellen und deine Form2 kennt somit anschließend die von X veröffentlichten Methoden.
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Sa 24.04.10 12:37 
Ralf war schneller, ... :o

Aber macht ja eigentlich auch keinen Sinn von außen eine generische Klasse zu setzen und dann in der klasse (Form1) doch ein konkrete Klasse zu verwenden.

Ich denke es macht nur sowas Sinn:

ausblenden C#-Quelltext
1:
2:
3:
4:
public partial class Form2<T> : Form
{
   public T Generic { get; set; }
}


ausblenden C#-Quelltext
1:
2:
3:
Form2<X> xForm = new Form2<X>(new X());

xForm.Generic.M();


Gruß & schönes Wochenende & schönes Wetter :D
tomwendel
Hält's aus hier
Beiträge: 5

Windows 7
C#, C++ in Visual Studio 2010
BeitragVerfasst: Sa 24.04.10 12:41 
Hey Ralf,

natürlich gibts M an der Stelle nicht. Du arbeitest ja mit einem generischen Datentypen. Da in a prinzipiell alles drin stecken kann, erlaubt der Compiler hier auch keine typspezifischen Dinge. Erste Frage wär an dieser Stelle, warum du hier mit generischen Datentypen arbeiten willst, wenn du dann doch einen bestimmten Datentypen erwartest? Frage 2: Warum versuchst du das nicht mit der klassischen Vererbung (Konstruktor erwartet Basisklasse die über Methode M verfügt) zu lösen?

Wenn du auf Generics bestehst, kannst du noch den Datentypen, der in T stecken kann, einzuschränken. Mit der Syntax
class X<T> where T : IComparable
kannst du den enthaltenen Datentypen einschränken und damit sicher stellen, dass Methoden vorhanden sind.

Cheers
tomwendel
Hält's aus hier
Beiträge: 5

Windows 7
C#, C++ in Visual Studio 2010
BeitragVerfasst: Sa 24.04.10 12:41 
Ihr seid verdammt schnell hier :)
maxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70



BeitragVerfasst: Sa 24.04.10 12:58 
Mal Danke für die vielen Antworten :)

Zitat:
ausblenden C#-Quelltext
1:
2:
3:
4:
public partial class Form2<TA> : Form where TA : X
{
  ....
}

Aber macht ja eigentlich auch keinen Sinn von außen eine generische Klasse zu setzen und dann in der klasse (Form1) doch ein konkrete Klasse zu verwenden.


Da gebe ich danielf Recht. Dann könnte ich ja gleich komplett auf Generic verzichten.

ausblenden C#-Quelltext
1:
2:
Form2<X> xForm = new Form2<X>(new X());
xForm.Generic.M();


Ich würde aber gerne INNERHALB von Form2 mit Methoden des übergebenen Objekts arbeiten.

Zitat:
wenn du dann doch einen bestimmten Datentypen erwartest?


Erwarte ich nicht. Es sollte dann möglich sein, auch noch andere Objekte (anderer Klassen) zu übergeben.
Die haben dann alle so eine Methode M().

Zitat:
Warum versuchst du das nicht mit der klassischen Vererbung


Geht nicht. Ich möchte dann nicht nur 1 Parameter, sondern 2 generisch übergeben. Also:
Form2<X,y> form2 = new Form2<X,y>(new X(),new Y());

EDIT:
Kann man das mittels 'where' irgendwie aufbohren, damit ich dann doch noch M() verwenden darf (ohne dass ich eine konkrete Klasse hinzuschreibe)? Vielleicht wenn ich ein Interface definiere und das dann dort angebe? Könnte ich dann nicht nur mit M(), sondern auch mit Eigenschaften arbeiten?
maxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70



BeitragVerfasst: Sa 24.04.10 13:15 
HA! mit Properties gehts:

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:
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
   public partial class Form1 : Form
   {
      public Form1()
      {
         InitializeComponent();
      }

      private void button1_Click(object sender, EventArgs e)
      {
         Form2<X> form2 = new Form2<X>(new X());
         form2.Show();
      }
   }
   public interface IA
   {
      int i { get; set; }
      void M();
   }
   public class X: IA
   {
      public int i { get; set; }
      public X()
      {
         this.i = 1;
      }
      public void M()
      {
         MessageBox.Show("m");
      }
   }
}

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
   public partial class Form2<TA> : Form where TA : IA
   {
      public Form2(TA a)
      {
         InitializeComponent();
         a.M();
         MessageBox.Show(a.i.ToString());
      }
   }
}


Allerdings könnte ich dann gleich komplett auf Generic verzichten und statt dessen gleich ganz normal ein IA übergeben. Also so:

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:
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
   public partial class Form1 : Form
   {
      public Form1()
      {
         InitializeComponent();
      }

      private void button1_Click(object sender, EventArgs e)
      {
         Form2 form2 = new Form2(new X());
         form2.Show();
      }
   }
   public interface IA
   {
      int i { get; set; }
      void M();
   }
   public class X: IA
   {
      public int i { get; set; }
      public X()
      {
         this.i = 1;
      }
      public void M()
      {
         MessageBox.Show("m");
      }
   }
}

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
   public partial class Form2: Form
   {
      public Form2(IA a)
      {
         InitializeComponent();
         a.M();
         MessageBox.Show(a.i.ToString());
      }
   }
}
maxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70



BeitragVerfasst: Sa 24.04.10 13:20 
Gibts vielleicht doch noch eine andere Möglichkeit mit Generic, bei der ich kein Interface und Properties unbedingt benötige?
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Sa 24.04.10 13:28 
Um ein Interface wirst Du wohl nicht drum herum kommen, denn irgendwo muss die Information ja drinstecken, dass die Methode "M" vorhanden ist :nixweiss:

Reflection vielleicht noch, aber das ist kein wirklich schöner Weg.

_________________
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: Sa 24.04.10 14:45 
Zitat:
Gibts vielleicht doch noch eine andere Möglichkeit mit Generic, bei der ich kein Interface und Properties unbedingt benötige?


Ein Gedankenexperiment. Stell dir vor dein Ausgangsbeispiel würde funktionieren. Was soll passieren wenn du deiner Form2 Klasse eine Klasse als generischen Typ übergibst die keine M Methode hat? Letztlich könnte das beim Aufruf zur Laufzeit nur furchtbar knallen oder der Aufruf wird einfach ignoriert (wie z.B bei nicht implementierten partiellen Methoden) was ich für noch schlimmer halten würde. Da ist es doch deutlicher besser wen das schon zur Compilezeit geprüft wird.

In deinem letzten Post hast du angedeutet das du die Klasse mit einem definierten Interface dann ja auch so übergeben könntest. Das mag sogar besser sein, läßt sich letztlich mit den wenigen Informationen die wir haben nicht beurteilen aber doch vermuten. Der generische Ansatz ist nicht für jedes Problem der günstigste Ansatz.
maxx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 70



BeitragVerfasst: Sa 24.04.10 15:17 
Zitat:
Was soll passieren wenn du deiner Form2 Klasse eine Klasse als generischen Typ übergibst die keine M Methode hat? Letztlich könnte das beim Aufruf zur Laufzeit nur furchtbar knallen

Ich habe Generics so verstanden, dass erst zur Laufzeit gewisse Kontrollen erfolgen. Das ist hier aber nicht der Fall. Es wird nicht zur Laufzeit kontrolliert, ob es eine Methode M gibt, sondern schon beim ersten Kompilieren.

Schon verwirrend, dieses Generics.
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Sa 24.04.10 16:17 
user profile iconmaxx hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Was soll passieren wenn du deiner Form2 Klasse eine Klasse als generischen Typ übergibst die keine M Methode hat? Letztlich könnte das beim Aufruf zur Laufzeit nur furchtbar knallen

Ich habe Generics so verstanden, dass erst zur Laufzeit gewisse Kontrollen erfolgen.

Das ist falsch. Das wären Dynamics, die mit .NET 4.0 eingeführt wurden. Sehe ich aber immer noch mit gespaltenen Gefühlen, dieses Feature :?

user profile iconmaxx hat folgendes geschrieben Zum zitierten Posting springen:
Das ist hier aber nicht der Fall. Es wird nicht zur Laufzeit kontrolliert, ob es eine Methode M gibt, sondern schon beim ersten Kompilieren.

Genau, so ist das auch richtig bei Generics.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".