Gå til innhold

Anbefalte innlegg

Heisan folkens

Har et problem som jeg må løse som går på å ha override på virtuals i instanser lagret i en liste.

 

Se for deg denne klassen

class Scheduler
{
 public virtual void Callback()
 {
 }
}

 

det jeg trenger er å legge inn instanser av denn eklassen i en liste ( list<oppgaver> mineOppgaver) samtidig som jeg bestemmer hendelsen i Callback metoden. Jeg prøvde meg på følgende som ikke kompilerer dessverre:

public void LeggTilOppgave(Oppgave o)
{
 class minScheduler : Scheduler
 {
   public override Callback()
   {
        // Kode som skal håndere hva som skal skje
   }
 }
 DefinerteOppgaver.Add(minScheduler)
}

Det er mange grunner til at dette ikke vil virke, men først og fremst fordi det ikek lar seg gjøre å lage en ny klasse på det SCOPE som dette eksemplet viser. Har noen en ide om hvordan dette kan gjøres så hadde det vert utrolig bra.

Lenke til kommentar
Videoannonse
Annonse

?

skjønner ikke helt hva du vil her, men det som ofte kan være lurt, er å lage et interface, istedet.

 

public interface ICallback
{
 void Callback();
}

public class Schedule : ICallback
{
 public void Callback()
 {
   MessageBox.Show("HAI!");
 }
}

public class ListItems
{
 protected List<ICallback> m_list;

 public void Enum()
 {
   foreach(ICallback call in m_list)
     call.Callback();
 }
 
}

 

edit: her kommer egentlig en av de store fordelene med interfaces, fordi man kan sjekke om et objekt arver fra et interface med "is" operator

 


public interface IRenderable
{
 public void Render(Graphics g);
}

public class BaseItem
{
 private Point m_pos;
 private Size m_size;

 public Point Position { get { return m_pos; } set { m_pos = value; } }
 public Size Size { get { return m_size; } set { m_size = value; } }
}

public class RectangleItem : BaseItem, IRenderable
{
 public void Render(Graphics g)
 {
   // Matrisen til g blir endret, slik at origo blir m_pos
   g.DrawRectangle(Pens.Black, new Point(0, 0), m_size);
 }
}

public class Renderer
{
 private List<BaseItem> m_items;
 public List<BaseItem> Items { get { return m_items; } }
 public void Render(Graphics g)
 {
   Matrix tmp_mat = g.Transform.Clone() as Matrix; // Lagre grunnmatrisen til senere bruk
   foreach(BaseItem item in m_items)
   {
     g.TranslateTransform(item.Position.X, item.Position.Y);
     if( item is IRenderable)  // Sjekk om objektet er IRenderable
       (item as IRenderable).Render(g);
     g.Transform = tmp_mat.Clone() as Matrix; // Kopier gammel matrise
   }
 }
}

 

edit: Legger til litt om virtuals også

 

EN virtual funksjon, kan overrides med override nøkkelordet, men du må lage en NY klasse, hvis du ikke vil lage en ny klasse, må du bruke delegates, eller events

 

virtual:

public abstract class absfoo
{
 public abstract int foofun();
}
public class virfoo
{
 public virtual int foofun()
 {
 }
}

public class inabsfoo : absfoo
{
 public override int foofun()
 {
 }
}

public class invirfoo : virfoo
{
 public override int foofun()
 {
 }
}

 

Merk at new kan også bruke til å override en funksjon som ikke er virtual, men dette vil få uønskede konsekvenser hvis det brukes i en array av forskjellige typer.

 

public class fooclass
{
 public int foo()
 {
 }
}

public class infoo : fooclass
{
 public new int foo()
 {
 }
}

 

delegates gjør at man kan endre disse funksjonene uavhengig av datatypen

 

public delegate int foodef();

public class foo
{
 public foodef foo;
 public int do_foo()
 {
   Console.WriteLine("Foo!");
   return -1;
 }
}

public class somefoo
{
 public somefoo()
 {
   foo new_foo = new foo();
   new_foo.foo = new_foo.do_foo;
   new_foo.foo();
 }
}

Endret av GeirGrusom
Lenke til kommentar

Mulig jeg forklarte meg litt klønete. For å svare på spørsmålet mit kan du heller gjøre følgende:

 

Lag en enkel klasse, kall den MyClass, som inneholder en virtuel metode. Det vil si at koden som instansierer denne klassen kan selv inneholde den koden som skal kjøres i denne virtuelle metoden. Dette er jo hele poenget med virtuals.

 

Så kan du definere en list<MyClass>

 

Hvis du da kan vise meg hvordan du definerer koden i den virtuelle metoden så hadde det vert genialt bra. Husk at denne koden ikke nødvendigvis behøver være den samme for alle elementene i listen. Er faktisk mulig jeg ber om for mye her nå ;-)

Lenke til kommentar

ok sånn virker virrtuals:

 

- Først definerer du en klasse med en virtual metode

public class MyClass
{
 public virtual void Foo()
 {
   MessageBox.Show("Første virtual metode");
 }
}

 

Deretter må du lage en klasse som inheriter fra MyClass, og skriver over Foo

 

public class MySecondClass : MyClass
{
 public override void Foo()
 {
   MessageBox.Show("My overriden virtual function! :D");
 }
}

 

Deretter kan du legge disse inn i en liste

 

public static class MyProgramClass
{
 public static void Main()
 {
   List<MyClass> my_list = new List<MyClass>();

   my_list.Add(new MyClass());
   my_list.Add(new MySecondClass() as MyClass);

   foreach(MyClass cl in my_list)
     cl.Foo();
 }
}

Lenke til kommentar

Haha! Dette sa meg ikke noe nytt gitt ;-)

 

Men tråden kan stenges da det jeg spør om ikke lar seg så lett gjøre. Jeg løste egentlig problemet mye bedre med Eventer. Takk til deg Geir den Grusome for mail om dette. Det tok litt tid før jeg skjønte mailen din. I natt ved 4 tiden fikk jeg et skikkelig lys i hodet og plutselig gikk det opp for meg hvor enkelt dette med eventer egentlig er :-D

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...