问题描述
我是新的C#的世界,我试图环绕仿制药我的头。这是我当前的问题:
I'm new to the c# world, and I'm trying to wrap my head around generics. Here is my current problem:
public Interface IAnimal{
string getType();
}
public Interface IAnimalGroomer<T> where T:IAnimal{
void groom(T);
}
现在我想有一个包含这些动物美容师字典来。我怎么做?在Java中,我可以做这样的事情:
Now I want to have a dictionary that contains these animal groomers. How do I do that? In java, I could do something like this:
HashMap<String,IAnimalGroomer<?>> groomers = new HashMap<>();
编辑:这是我想要做的一个例子:
Here is an example of what I'm trying to do:
public class Dog : IAnimal
{
public string GetType()
{
return "DOG";
}
public void ClipNails() { }
}
public class DogGroomer : IAnimalGroomer<Dog>
{
public void Groom(Dog dog)
{
dog.ClipNails();
}
}
public class Program
{
private List<IAnimalGroomer<IAnimal>> groomers = new List<IAnimalGroomer<IAnimal>>();
public void doSomething()
{
//THIS DOESN"T COMPILE!!!!
groomers.Add(new DogGroomer());
}
}
修改
我想我的意图是在原来的职位还不清楚我的最终目标是使采用不同类型的IAnimalGroomers的AnimalGroomerClinic然后动物业主可以在诊所下车动物,诊所可以决定哪些美容师应该照顾的动物:
EDITI think my intentions were unclear in the original post. My ultimate goal is to make an AnimalGroomerClinic that employs different types of IAnimalGroomers. Then animal owners can drop off animals at the clinic, and the clinic can decide which groomer should take care of the animal:
public class AnimalGroomerClinic
{
public Dictionary<String, IAnimalGroomer> animalGroomers = new Dictionary<String,IAnimalGroomer>();
public void employGroomer(IAnimalGroomer groomer){
animalGroomers.add(groomer.getAnimalType(), groomer);
}
public void Groom(IAnimal animal){
animalGroomers[animal.getAnimalType()].Groom(animal);
}
}
我知道我可以做到这一点,而不使用泛型。但是,仿制药让我写这样的方式,它是捆绑(在编译时)为 IAnimal 特定实例的
IAnimalGroomer
接口code>。此外, IAnimalGroomer
不需要现浇混凝土,这些类 IAnimals
所有的时间,因为仿制药将迫使实现对付一个特定的一种动物。我已经在Java中使用过这个成语,而我只是想知道,如果有把它写在C#中类似的方式
I realize I could do this without using generics. But the generics allow me to write the IAnimalGroomer
interface in such a way that it is tied (at compile time) to a specific instance of IAnimal
. In addition, concrete classes of IAnimalGroomer
don't need to cast their IAnimals
all the time, since generics would force implementations to deal with one specific kind of animal. I have used this idiom before in Java, and I'm just wondering if there is a similar way to write it in C#.
编辑2:
很多有趣的讨论。我接受这样向我指出动态调度在评论一个答案。
Edit 2:Lots of interesting discussion. I'm accepting an answer that pointed me to dynamic dispatching in the comments.
推荐答案
作为的指出了上述评论,也许动态
是去这里的道路。
As Brian pointed out in comments above, maybe dynamic
is the way to go here.
看看下面的代码。你得到仿制药的优势很好地牵制了API,并在使用抽油烟机动态
来使事情工作的
Check out the following code. You get the benefits of generics to tie down the API nicely and under the hoods you use dynamic
to make things work.
public interface IAnimal
{
}
public class Dog : IAnimal
{
}
public class Cat : IAnimal
{
}
public class BigBadWolf : IAnimal
{
}
//I changed `IAnimalGroomer` to an abstract class so you don't have to implement the `AnimalType` property all the time.
public abstract class AnimalGroomer<T> where T:IAnimal
{
public Type AnimalType { get { return typeof(T); } }
public abstract void Groom(T animal);
}
public class CatGroomer : AnimalGroomer<Cat>
{
public override void Groom(Cat animal)
{
Console.WriteLine("{0} groomed by {1}", animal.GetType(), this.GetType());
}
}
public class DogGroomer : AnimalGroomer<Dog>
{
public override void Groom(Dog animal)
{
Console.WriteLine("{0} groomed by {1}", animal.GetType(), this.GetType());
}
}
public class AnimalClinic
{
private Dictionary<Type, dynamic> groomers = new Dictionary<Type, dynamic>();
public void EmployGroomer<T>(AnimalGroomer<T> groomer) where T:IAnimal
{
groomers.Add(groomer.AnimalType, groomer);
}
public void Groom(IAnimal animal)
{
dynamic groomer;
groomers.TryGetValue(animal.GetType(), out groomer);
if (groomer != null)
groomer.Groom((dynamic)animal);
else
Console.WriteLine("Sorry, no groomer available for your {0}", animal.GetType());
}
}
和现在你可以这样做:
var animalClinic = new AnimalClinic();
animalClinic.EmployGroomer(new DogGroomer());
animalClinic.EmployGroomer(new CatGroomer());
animalClinic.Groom(new Dog());
animalClinic.Groom(new Cat());
animalClinic.Groom(new BigBadWolf());
我不知道这是什么有点你要找的。希望它能帮助!
I'm not sure if this is somewhat what you were looking for. Hope it helps!
这篇关于C#泛型:通配符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!