我有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'的引用。
封装的原则是客户不应该知道“动物”,只知道中间人(“农民”)。
我该如何解决这个问题,为什么会出现?
答案 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实现,这会引发错误。
说明:
类型参数是客户端的特定类型的占位符 指定何时实例化泛型类型的变量
这意味着任何需要Generic Type参数的类的实例变量必须在其实例化时传递它所需的Type。
在您的情况下,您不需要在实例化期间传递类型
var cowFarmer = new CowFarmer();
因为您已经指定了Type参数和类。 (如果双击错误,假设您使用的是Visual Studio,它甚至会指向上面的行。)
public class CowFarmer: AbstractFarmer<Cow>
但是,在实例化时,Cow
类现在需要与cowFarmer
变量(存在于客户端程序集中)绑定,并且该变量需要实例化完全需要引用动物集合,其中包含Cow
类。
我认为,这是导致您混淆的原因 - Type
Cow
,在cowFarmer
实例化时无法直接显示。