Jump to content
  • 0

pomoc C# overload generik v derived classe


Deleted User

Dotaz

Nejaky C# master, ktory by mi vedel poradit s generikami a ich pretazovanim v potomkoch classy?

Tu je moj kod:

using System;
using System.Collections.Generic;
					
public class Program {
	static void Visit(Visitor visitor) {
		var animal = new List<Animal>();
		var cat = new List<Cat>();
		
		visitor.Visit(animal);
		visitor.Visit(cat);
	}
	
	public static void Main() {
		Visit(new Visitor());
		Visit(new FirstVisitor());
		Visit(new SecondVisitor());
		Visit(new ThirdVisitor());
	}
	
	public class Visitor {
		public virtual void Visit<T>(List<T> objects) where  T : Animal {
			Console.WriteLine("Called visit from base visitor");
		}
	}
	
	public class FirstVisitor : Visitor {
		public void Visit(List<Cat> cats) {
			Console.WriteLine("called cats from first visitor");		
		}
	}
	
	public class SecondVisitor : Visitor {
		public void Visit(List<Animal> cats) {
			Console.WriteLine("called animal from second visitor");		
		}
	}
	
	public class ThirdVisitor : Visitor {
		public override void Visit<T>(List<T> objs) {
			Console.WriteLine("called obj from third visitor");		
		}
	}
	
	
	public class Animal {
		
	}
	
	public class Cat : Animal {
		
	}
}

Vystup je:

Called visit from base visitor
Called visit from base visitor
Called visit from base visitor
Called visit from base visitor
Called visit from base visitor
Called visit from base visitor
called obj from third visitor
called obj from third visitor

https://dotnetfiddle.net/

Problem je, ze pretazene metody vo First a Second visitore sa vobec nevolaju.

Povodne to je kus C++ kodu, ktory potrebujem v podobnom style prepisat do C#

Link to comment
Share on other sites

3 odpovědí na tuto otázku

Recommended Posts

  • 0

Tvoja statická metóda Visit má parameter typu Visitor. Ak na objekte uloženom v premennej typu Visitor zavoláš metódu, zavolá sa metóda z triedy Visitor (ak táto metóda nie je virtual a skutočný typ objektu túto metódu pomocou override nepreťažuje).

Metódy sa mi volali správne, keď som ich volal na objektoch uložených v premenných správneho typu (FirstVisitor, SecondVisitor, ... nie Visitor) a v tomto prípade nebolo potrebné používať virtual / override.

Spoiler

public static void Main()
{
    Console.WriteLine("===== Visitor =====");
    var visitor = new Visitor();
    visitor.Visit(new List<Animal>());
    visitor.Visit(new List<Cat>());

    Console.WriteLine("===== First Visitor =====");
    var firstVisitor = new FirstVisitor();
    firstVisitor.Visit(new List<Animal>());
    firstVisitor.Visit(new List<Cat>());

    Console.WriteLine("===== Second Visitor =====");
    var secondVisitor = new SecondVisitor();
    secondVisitor.Visit(new List<Animal>());
    secondVisitor.Visit(new List<Cat>());

    Console.WriteLine("===== Third Visitor =====");
    var thirdVisitor = new ThirdVisitor();
    thirdVisitor.Visit(new List<Animal>());
    thirdVisitor.Visit(new List<Cat>());
}

 

 

Prípadne sa mi to ešte podarilo pridaním negenerických virtuálnych metód do Visitora, ktoré potom v derived triedach overridujem:

Spoiler

using System;
using System.Collections.Generic;

public class Program
{
	static void Visit(Visitor visitor)
	{
		var cats = new List<Cat>();
		var animals = new List<Animal>();
		var dogs = new List<Dog>();

		Console.WriteLine(visitor.GetType().Name);
		visitor.Visit(cats);
		visitor.Visit(animals);
		visitor.Visit(dogs);
	}

	public static void Main()
	{
		Visit(new Visitor());
		Visit(new FirstVisitor());
		Visit(new SecondVisitor());
		Visit(new ThirdVisitor());
	}

	public class Visitor
	{
		public virtual void Visit(List<Cat> cats)
		{
			Console.WriteLine("Visitor - Cats");
		}

		public virtual void Visit(List<Animal> animals)
		{
			Console.WriteLine("Visitor - Animals");
		}

		public virtual void Visit<T>(List<T> objects) where T : Animal
		{
			Console.WriteLine("Visitor - Generic");
		}
	}

	public class FirstVisitor : Visitor
	{
		public override void Visit(List<Cat> cats)
		{
			Console.WriteLine("FirstVisitor - Cats");
		}

		public override void Visit(List<Animal> animals)
		{
			Console.WriteLine("FirstVisitor - Animals");
		}

		public override void Visit<T>(List<T> objs)
		{
			Console.WriteLine("FirstVisitor - Generic");
		}
	}

	public class SecondVisitor : Visitor
	{
		public override void Visit(List<Cat> cats)
		{
			Console.WriteLine("SecondVisitor - Cats");
		}

		public override void Visit(List<Animal> animals)
		{
			Console.WriteLine("SecondVisitor - Animals");
		}

		public override void Visit<T>(List<T> objs)
		{
			Console.WriteLine("SecondVisitor - Generic");
		}
	}

	public class ThirdVisitor : Visitor
	{
		public override void Visit(List<Cat> cats)
		{
			Console.WriteLine("ThirdVisitor - Cats");
		}

		public override void Visit(List<Animal> animals)
		{
			Console.WriteLine("ThirdVisitor - Animals");
		}

		public override void Visit<T>(List<T> objs)
		{
			Console.WriteLine("ThirdVisitor - Generic");
		}
	}

	public class Animal
	{

	}

	public class Cat : Animal
	{

	}

	public class Dog : Animal
	{ 
	
	}
}

 

Výstup je potom:

Spoiler

Visitor
Visitor - Cats
Visitor - Animals
Visitor - Generic
FirstVisitor
FirstVisitor - Cats
FirstVisitor - Animals
FirstVisitor - Generic
SecondVisitor
SecondVisitor - Cats
SecondVisitor - Animals
SecondVisitor - Generic
ThirdVisitor
ThirdVisitor - Cats
ThirdVisitor - Animals
ThirdVisitor - Generic

 

 

Edited by DuFF
Link to comment
Share on other sites

  • 0
před 8hodinami, DuFF said:

Tvoja statická metóda Visit má parameter typu Visitor. Ak na objekte uloženom v premennej typu Visitor zavoláš metódu, zavolá sa metóda z triedy Visitor (ak táto metóda nie je virtual a skutočný typ objektu túto metódu pomocou override nepreťažuje).

Metódy sa mi volali správne, keď som ich volal na objektoch uložených v premenných správneho typu (FirstVisitor, SecondVisitor, ... nie Visitor) a v tomto prípade nebolo potrebné používať virtual / override.

  Ukázat skrytý obsah


public static void Main()
{
    Console.WriteLine("===== Visitor =====");
    var visitor = new Visitor();
    visitor.Visit(new List<Animal>());
    visitor.Visit(new List<Cat>());

    Console.WriteLine("===== First Visitor =====");
    var firstVisitor = new FirstVisitor();
    firstVisitor.Visit(new List<Animal>());
    firstVisitor.Visit(new List<Cat>());

    Console.WriteLine("===== Second Visitor =====");
    var secondVisitor = new SecondVisitor();
    secondVisitor.Visit(new List<Animal>());
    secondVisitor.Visit(new List<Cat>());

    Console.WriteLine("===== Third Visitor =====");
    var thirdVisitor = new ThirdVisitor();
    thirdVisitor.Visit(new List<Animal>());
    thirdVisitor.Visit(new List<Cat>());
}

 

 

Prípadne sa mi to ešte podarilo pridaním negenerických virtuálnych metód do Visitora, ktoré potom v derived triedach overridujem:

  Ukázat skrytý obsah


using System;
using System.Collections.Generic;

public class Program
{
	static void Visit(Visitor visitor)
	{
		var cats = new List<Cat>();
		var animals = new List<Animal>();
		var dogs = new List<Dog>();

		Console.WriteLine(visitor.GetType().Name);
		visitor.Visit(cats);
		visitor.Visit(animals);
		visitor.Visit(dogs);
	}

	public static void Main()
	{
		Visit(new Visitor());
		Visit(new FirstVisitor());
		Visit(new SecondVisitor());
		Visit(new ThirdVisitor());
	}

	public class Visitor
	{
		public virtual void Visit(List<Cat> cats)
		{
			Console.WriteLine("Visitor - Cats");
		}

		public virtual void Visit(List<Animal> animals)
		{
			Console.WriteLine("Visitor - Animals");
		}

		public virtual void Visit<T>(List<T> objects) where T : Animal
		{
			Console.WriteLine("Visitor - Generic");
		}
	}

	public class FirstVisitor : Visitor
	{
		public override void Visit(List<Cat> cats)
		{
			Console.WriteLine("FirstVisitor - Cats");
		}

		public override void Visit(List<Animal> animals)
		{
			Console.WriteLine("FirstVisitor - Animals");
		}

		public override void Visit<T>(List<T> objs)
		{
			Console.WriteLine("FirstVisitor - Generic");
		}
	}

	public class SecondVisitor : Visitor
	{
		public override void Visit(List<Cat> cats)
		{
			Console.WriteLine("SecondVisitor - Cats");
		}

		public override void Visit(List<Animal> animals)
		{
			Console.WriteLine("SecondVisitor - Animals");
		}

		public override void Visit<T>(List<T> objs)
		{
			Console.WriteLine("SecondVisitor - Generic");
		}
	}

	public class ThirdVisitor : Visitor
	{
		public override void Visit(List<Cat> cats)
		{
			Console.WriteLine("ThirdVisitor - Cats");
		}

		public override void Visit(List<Animal> animals)
		{
			Console.WriteLine("ThirdVisitor - Animals");
		}

		public override void Visit<T>(List<T> objs)
		{
			Console.WriteLine("ThirdVisitor - Generic");
		}
	}

	public class Animal
	{

	}

	public class Cat : Animal
	{

	}

	public class Dog : Animal
	{ 
	
	}
}

 

Výstup je potom:

  Ukázat skrytý obsah


Visitor
Visitor - Cats
Visitor - Animals
Visitor - Generic
FirstVisitor
FirstVisitor - Cats
FirstVisitor - Animals
FirstVisitor - Generic
SecondVisitor
SecondVisitor - Cats
SecondVisitor - Animals
SecondVisitor - Generic
ThirdVisitor
ThirdVisitor - Cats
ThirdVisitor - Animals
ThirdVisitor - Generic

 

 

Problem je, mam viac potomkov visitorov, a metody beru na vstupe iba Visitor, rovnako ako v danom priklade.
S tymi negenerickymi metodami je ten problem, ze ja neviem dopredu, kolko potomkov bude mat trieda Animal, takze metodu Visit negenericky napisat nemozem, pac potrebujem fallbacky, ak metoda nie je pre specificky typ pretazena.

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...