Laden...

In abstrakter Basisklasse eine Methode mit Rückgabewert vom Typ der Subklasse definieren

Erstellt von TiltonJH vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.022 Views
TiltonJH Themenstarter:in
87 Beiträge seit 2006
vor 13 Jahren
In abstrakter Basisklasse eine Methode mit Rückgabewert vom Typ der Subklasse definieren

Hallo,

folgende Situation:


public abstract class Base<T> where T : class
{
	//...

	public T GetThis()
	{
		return this;
	}

	//...
}

public class SomeClass : Base<SomeClass>
{
	//...
}

Kann man sowas auch ohne Generic lösen? Also das, ich in der Base class mit dem egl Typ des Objekts arbeiten kann ohne ihn per Gerneric bekannt geben zu müssen?

MfG

TiltonJH

"In der Informatik geht es genauso wenig um Computer wie in der Astonomie um Teleskope."
Edsger W. Dijkstra

The Humble Programmer by Edsger W. Dijkstra

2.298 Beiträge seit 2010
vor 13 Jahren

Klar, du kannst ganz normal wie folgt vorgehen:


public abstract class Base
{
    //...
}

public class SomeClass : Base
{
    //...
} 

Du musst dann jedoch außerhalb der Klasse casten. - Die Basisklasse selbst sollte intern sowieso keine Ahnung haben, was SomeClass macht.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

Also das, ich in der Base class mit dem egl Typ des Objekts arbeiten kann ohne ihn per Gerneric bekannt geben zu müssen?

Wozu soll das gut sein? Eine Basisklasse sollte ihre Kindklassen nicht kennen und schon gar nicht funktional benötigen.

Deine Basisklasse ist doch ohnehin schon abstract. Dann sollte alles aus den Kindklassen Benötigte auch abstract sein.

Du kannst der abstrakten Basisklasse auch ein Interface verpassen, und dieses erst in den Kindklassen implementieren, und dann in Deiner GetThis-Methode das Interface zurückgeben.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

TiltonJH Themenstarter:in
87 Beiträge seit 2006
vor 13 Jahren

@inflames2k: sorry, aber ich glaube du hast das problem nicht verstanden. die GetThis methode is der dreh und angelpunkt, und die gibt es natürlich kein prob.

@MarsStein: auch du hast nich verstanden nach was ich gefragt habe.

Ich möchte in der basisklasse eine methode, ein property, oder ein feld anlegen, welches aber nich vom typ der basisklasse ist, sondern von der jeweiligen subklasse. da (wie MarsStein richtig feststellte) eine basisklasse nicht wissen kann / sollte welche subklassen es gibt, lässt sich das prob nur über generic (s.o.) lösen

was ich suche ist nach einem weg ohne generic zu nutzen.

ein objekt (die instanz einer klasse) weis ja von welchem konkreten typ sie ist, ergo such ich etwas in der form:


public abstract class Base
{
    //...

    public derivedClass GetThis()
    {
        return this;
    }

    //...
}

public class SomeClass : Base
{
    //...
}

MfG

Tilton

"In der Informatik geht es genauso wenig um Computer wie in der Astonomie um Teleskope."
Edsger W. Dijkstra

The Humble Programmer by Edsger W. Dijkstra

6.862 Beiträge seit 2003
vor 13 Jahren

Hallo,

das geht nicht, genau für sowas sind Generics doch da. Warum willst du ohne die arbeiten?

Baka wa shinanakya naoranai.

Mein XING Profil.

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

was ich suche ist nach einem weg ohne generic zu nutzen.

Den wird es IMHO nicht geben. Irgendwo musst Du ja den Typen bekanntmachen, den Du zurückgeben willst, und wenn dieser variabel sein soll geht nur, indem Du entweder eine gemeinsame Basisklasse zurückgibst (und von außen castest), oder eben mit der generischen Lösung.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

TiltonJH Themenstarter:in
87 Beiträge seit 2006
vor 13 Jahren

das geht nicht, genau für sowas sind Generics doch da. Warum willst du ohne die arbeiten?

Schade X( !
Warum weil ich zu faul bin mein ganzes ObjektModel auf eben diese Generic-Geschichte umzustellen 😄.

Und ich wird dachte das den jeweiligen Typ der SubKlasse nach unten zu geben is komisch, das könnte man doch standardmässig so vorsehn, zb über ein key-wort das ich noch nich kenne 😉 .

MfG

Tilton

"In der Informatik geht es genauso wenig um Computer wie in der Astonomie um Teleskope."
Edsger W. Dijkstra

The Humble Programmer by Edsger W. Dijkstra

5.742 Beiträge seit 2007
vor 13 Jahren

Hallo TiltonJH,

in manchen Fällen kann man das mit new lösen - aber man sollte wirklich genau wissen, wann und wann nicht; Generics sind meist der geeignetere Weg.


public abstract class Base
{
   private readonly object _value;

   public object Value { get { return this._value; } }

   protected Base(object value) { this._value = value; }
}

public sealed class Sub : Base
{
   public Sub(string value) : base(value) { }
   
   public new string Value { get { return (string) base.Value; } }
}

TiltonJH Themenstarter:in
87 Beiträge seit 2006
vor 13 Jahren

in manchen Fällen kann man das mit new lösen - aber man sollte wirklich genau wissen, wann und wann nicht; Generics sind meist der geeignetere Weg.

ne, ja, nee...

mir geht es ja genau darum die methoden (o.ä.) nich in den subklassen bekanntgeben oder überschreiben zu müssen, sondern diese per vererbung zu erhalten.

MfG

Tilton

"In der Informatik geht es genauso wenig um Computer wie in der Astonomie um Teleskope."
Edsger W. Dijkstra

The Humble Programmer by Edsger W. Dijkstra

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

in manchen Fällen kann man das mit new lösen

Wobei ich die Verwendung von new in diesem Zusammenhang immer sehr hässlich finde.

aber man sollte wirklich genau wissen, wann und wann nicht;

Vor allem sollte es IMHO nur verwendet werden, wenn ein Ausnahmefall vorliegt, der von der Standardimplementierung abweicht.

In diesem speziellen Fall würde ich das nicht empfehlen, weil nicht ein Ausnahmefall behandelt würde, sondern es zum generellen Konzept gehören würde, daß die Kindklassen die Methode mit new überschreiben sollen/müssen. Und dafür ist es nicht gedacht.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

5.742 Beiträge seit 2007
vor 13 Jahren

wenn ein Ausnahmefall vorliegt, der von der Standardimplementierung abweicht.

Eben dann wäre es ja gerade nicht sinnvoll - da wäre dann ein override angebracht.
Aber gerade, wenn nicht nur eine, sondern zwei Klassen daziwschen liegen, ist der Einsatz von Generics manchmal gar nicht möglich. Insofern hat new hier IMHO durchaus eine Berechtigung.

2.298 Beiträge seit 2010
vor 13 Jahren

in manchen Fällen kann man das mit new lösen - aber man sollte wirklich genau wissen, wann und wann nicht; Generics sind meist der geeignetere Weg.

Das führt doch aber dennoch dazu, dass ein Cast außerhalb der Klasse notwendig ist. Und wenn ich ihn richtig verstehe will er genau das nicht.

Folgendes hab ich verstanden, will er erreichen:


Base base = new Sub();
Sub sub = base.GetThis();

Mit deiner Variante würde er zwangsläufig wieder folgendes schreiben müssen:


Base base = new Sub();
Sub sub = (Sub)base;

Das einzige was hier wirklich geeignet ist, ist die generische Variante.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo winSharp93,

Eben dann wäre es ja gerade nicht sinnvoll - da wäre dann ein override angebracht.

Naja ein override klappt ja nicht, da dann die Methodensignatur und damit der Rückgabetyp gleich sein muss.
Dann kann man auch einfach die Basismethode erben, es sei denn man will ein anderes Objekt zurückgeben als die Basisklasse, und nicht dasselbe Objekt als anderen Typen.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

5.742 Beiträge seit 2007
vor 13 Jahren

Folgendes hab ich verstanden, will er erreichen

Gut, wenn das so ist, habt ihr natürlich recht - ich hatte es so verstanden, dass direkt Sub verwendet wird.

Naja ein override klappt ja nicht, da dann die Methodensignatur und damit der Rückgabetyp gleich sein muss.
Dann kann man auch einfach die Basismethode erben, es sei denn man will ein anderes Objekt zurückgeben als die Basisklasse, und nicht dasselbe Objekt als anderen Typen.

Ja - aber da hilft dann auch ein new nicht weiter - damit erzeugt man nur die Verwirrung, dass (bezogen auf die Implementierung) "base.Methode() != sub.Methode()". Somit sollte man new nur in Fällen einsetzen, in denen sich die Implementierung nicht ändert und man z.B. nur noch einen zusätzlichen Cast durchführt, den sonst der Verwender durchführen müsste.

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo winSharp93,

damit erzeugt man nur die Verwirrung, dass (bezogen auf die Implementierung) "base.Methode() != sub.Methode()". Somit sollte man new nur in Fällen einsetzen, in denen sich die Implementierung nicht ändert und man z.B. nur noch einen zusätzlichen Cast durchführt, den sonst der Verwender durchführen müsste. Dem stimme ich voll und ganz zu. Dennoch bleibe ich der Ansicht, daß new nur in Ausnahmefällen, bei manchen Ausreissern verwendet werden sollte, und nicht konzeptionell davon ausgegangen werden sollte, daß erbende Klassen bestimmte Member mit new zu überschreiben haben, um die weitere Funktionalität sicher zu stellen -> spätestens wenn ich an einen solchen Punkt käme, würde ich mein Design überdenken.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca