为什么客户项目需要引用基础项目和中间项目?

时间:2014-05-02 08:07:24

标签: c# .net visual-studio dll

我有3个项目:基础,中间和客户。客户端访问基础项目通过中间一个。我在这里简化了我的问题。我有一个包含3个项目的解决方案:

// Animals project
public class FarmAnimal
{
    public string GetFood { get; protected set; }
}

public class Cow : FarmAnimal
{
    public Cow()
    {
        GetFood = "Milk";
    }

}

public class Chicken : FarmAnimal
{
    public Chicken()
    {
        GetFood = "Egg";
    }

}

// Farmer project
public class AbstractFarmer<TAnimal> where TAnimal : FarmAnimal, new()
{
    protected TAnimal animal = new TAnimal();
    public string GetProduct()
    {
        return animal.GetFood;
    }
}

public class CowFarmer: AbstractFarmer<Cow>
{

}

public class ChickenFarmer : AbstractFarmer<Chicken>
{

}

// Client project
class Program
{
    static void Main(string[] args)
    {
        var cowFarmer = new CowFarmer();
        Console.WriteLine(cowFarmer.GetProduct());
    }
}

如果客户项目没有添加对动物的引用,那么它会给出:

  

错误1“Animals.FarmAnimal”类型在未引用的程序集中定义。您必须添加对程序集'Animals,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'的引用。

封装的原则是客户不应该知道“动物”,只知道中间人(“农民”)。

我该如何解决这个问题,为什么会出现?

1 个答案:

答案 0 :(得分:5)

将农民项目更改为

    public class AbstractFarmer
    {
        protected FarmAnimal animal;
        public string GetProduct()
        {
            return animal.GetFood;
        }
    }

    public class CowFarmer : AbstractFarmer
    {
        public CowFarmer()
        {
            animal = new Cow();
        }
    }

    public class ChickenFarmer : AbstractFarmer
    {
        public ChickenFarmer()
        {
            animal = new Chicken();
        }
    }

它应该可以正常工作。

当您向<Type>类明确提供动态AbstractFarmer时,您必须使用Animal所需的类型参数绑定您的Farmer实现,这会引发错误。

说明:

来自MSDN Documentation

  

类型参数是客户端的特定类型的占位符   指定何时实例化泛型类型的变量

这意味着任何需要Generic Type参数的类的实例变量必须在其实例化时传递它所需的Type。
在您的情况下,您不需要在实例化期间传递类型

var cowFarmer = new CowFarmer();  

因为您已经指定了Type参数和类。 (如果双击错误,假设您使用的是Visual Studio,它甚至会指向上面的行。)

public class CowFarmer: AbstractFarmer<Cow>

但是,在实例化时,Cow类现在需要与cowFarmer变量(存在于客户端程序集中)绑定,并且该变量需要实例化完全需要引用动物集合,其中包含Cow类。

我认为,这是导致您混淆的原因 - Type Cow,在cowFarmer实例化时无法直接显示。