【问题标题】:Why does a client project need reference both to the base and the intermediate project?为什么客户项目需要同时引用基础项目和中间项目?
【发布时间】:2014-05-02 08:07:23
【问题描述】:

我有 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”的引用。

封装原则说客户端不应该知道“Animals”,只知道中间体(“Farmers”)。

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

【问题讨论】:

  • "封装原理说客户端不应该知道“动物””——那你为什么要在你的Farmer项目中打破这个“封装”并暴露Cow和@987654325 @ 类型作为定义 CowFarmerChickenFarmer 类的一部分?

标签: c# .net visual-studio dll


【解决方案1】:

将 Farmer 项目更改为

    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();
        }
    }

它应该可以正常工作。

发生的情况是,当您将动态 &lt;Type&gt; 显式提供给 AbstractFarmer 类时,您必须将 Farmer 实现与引发错误的 Animal required 类型参数绑定。

解释:

来自MSDN Documentation

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

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

var cowFarmer = new CowFarmer();  

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

public class CowFarmer: AbstractFarmer<Cow>

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

我认为,这是造成您困惑的原因 - Type Cow,在 cowFarmer 实例化时不直接可见。

【讨论】:

  • 是的,它有效。 :) 你能否添加更多关于它为什么起作用的解释?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-03
  • 2015-06-06
  • 2012-11-13
  • 2020-03-27
  • 2012-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多