C#泛型:通配符 [英] C# Generics: wildcards

查看:374
本文介绍了C#泛型:通配符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新的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然后动物业主可以在诊所下车动物,诊所可以决定哪些美容师应该照顾的动物:

EDIT I 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#泛型:通配符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆