我正在尝试学习如何使用c#创建泛型类.有人可以解释为什么我运行这个程序时出现编译错误.
我创建了IZooAnimal接口.所有动物园动物都将实现此界面.
public interface IZooAnimal
{
string Id { get; set; }
}
public class Lion : IZooAnimal
{
string Id { get; set; }
}
public class Zebra : IZooAnimal
{
public string Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
ZooCage将容纳相同类型的动物
public class ZooCage<T> where T : IZooAnimal
{
public IList<T> Animals { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
动物园类有笼子
public class Zoo
{
public IList<ZooCage<IZooAnimal>> ZooCages { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用类的程序
class Program
{
static void Main(string[] args)
{
var lion = new Lion();
var lionCage = new ZooCage<Lion>();
lionCage.Animals = new List<Lion>();
lionCage.Animals.Add(lion);
var zebra = new Zebra();
var zebraCage = new ZooCage<Zebra>();
zebraCage.Animals = new List<Zebra>();
zebraCage.Animals.Add(zebra);
var zoo = new Zoo();
zoo.ZooCages = new List<ZooCage<IZooAnimal>>();
zoo.ZooCages.Add(lionCage);
}
}
Run Code Online (Sandbox Code Playgroud)
当我编译时,我得到以下错误:错误2参数1:无法从' ConsoleApplication2.ZooCage<ConsoleApplication2.Lion>' 转换为' ConsoleApplication2.ZooCage<ConsoleApplication2.IZooAnimal>'
为了让程序运行,我需要做哪些更改?
您不应该使用实现接口的具体类型来定义列表,而是使用接口来定义列表:
var lionCage = new ZooCage<IZooAnimal>();
lionCage.Animals = new List<IZooAnimal>();
Run Code Online (Sandbox Code Playgroud)
然后您的代码将按预期工作。
初始代码不起作用,因为不允许将具体类型转换为通用类型(正如 @default.kramer 指出的协变和逆变)。
我提出的解决方案如下:
// your ZooCage is still generic
public class ZooCage<T>
{
// but you declare on creation which type you want to contain only!
private Type cageType = null;
public ZooCage(Type iMayContain)
{
cageType = iMayContain;
animals = new List<T>();
}
// check on add if the types are compatible
public void Add(T animal)
{
if (animal.GetType() != cageType)
{
throw new Exception("Sorry - no matching types! I may contain only " + cageType.ToString());
}
animals.Add(animal);
}
// should be generic but not visible to outher world!
private IList<T> animals { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
此代码允许您执行以下操作:
var lion = new Lion();
var lionCage = new ZooCage<IZooAnimal>(typeof(Lion));
lionCage.Add(lion);
var zebra = new Zebra();
var zebraCage = new ZooCage<IZooAnimal>(typeof(Zebra));
zebraCage.Add(zebra);
Run Code Online (Sandbox Code Playgroud)
但它会抛出错误:
zebraCage.Add(lion);
Run Code Online (Sandbox Code Playgroud)
现在动物园可以安全地扩建了。
| 归档时间: |
|
| 查看次数: |
470 次 |
| 最近记录: |