我有一个基类ScenBase和一个派生类ScenC。我有一个类HexC派生形式基类Hex。我还有一个从基类Unit派生的UnitC类。我可以将Hex数组设置为指向HexC数组,但编译器不允许我将List of Unit设置为指向UnitC列表:
// The Core Database for the game scenario.
// Theoretically multiple secenarios can be loaded
// into memory at the same time.
[Serializable]
public class ScenC : ScenBase
{
public bool playable { get; set; }
public HexC[,] hexCs { get; private set; }
public List<UnitC> unitCs { get; private set; }
// A database for every user and AI entity.
public List<ScenV> chViews { get; private set; }
public List<string> characters { get; private set; }
public ScenC(int xDimI, int yDimI) : base (xDimI, yDimI)
{
playable = false;
chViews = new List<ScenV>();
characters = new List<string>();
characters.Add("Supreme");
hexCs = new HexC[xDim, yDim];
hexs = hexCs; //this line complies fine
newHex = (int x, int y) => new HexC(this, x, y);
unitCs = new List<UnitC>();
// **This line won't compile**
unitCs = units;
Init();
}
}
以下是基类ScenBase的字段属性:
[Serializable]
public abstract class ScenBase
{
public Hex[,] hexs;
public List<Unit> units { get; protected set; }
public DateTime currGameTime { get; set; }
public int xDim { get; set; }
public int yDim { get; set; }
public double scale { get; protected set; }
protected delegate Hex NewHex(int x, int y);
protected NewHex newHex;
//Rest of Class not shown for simplicity
}
为什么我不能在{是一个'隐式强制转换规则之后将List<Hex>
设置为List<HexC>
,但我可以将数组设置为数组
答案 0 :(得分:4)
这是不可能的。
如果有可能,您可以在列表中添加不同的派生类型 例如:
List<Car> cars = new List<Car>
List<Vehicle> vehicles = cars; //Error!
vehicles.Add(new Bicycle()); //That's not a car!
您要求的是协方差;它只能用于不可变接口(例如IEnumerable<T>
)
答案 1 :(得分:1)
您可以使用接口列表(1),其中Hex和Unit以某种方式符合指定接口。否则,你需要施放。
参考:http://msdn.microsoft.com/en-us/library/dd465120.aspx
btw:IEnumerable的任何接口都是协变的(参见:http://msdn.microsoft.com/en-us/library/9eekhta0.aspx)。语法:IEnumerable中的 out &lt; out T&gt;定义协方差。
(1)界面列表
using System;
using System.Collections.Generic;
public interface IHex {
string ToString();
}
public class Hex : IHex
{
public override string ToString() { return "Hex"; }
}
public interface IHexC : IHex {}
public class HexC : Hex
{
public override string ToString() { return "HexC"; }
}
public class Test{
public static void Main()
{
IList<IHex> HexList = new List<IHex>();
HexList.Add(new Hex());
HexList.Add(new HexC());
HexList.Add(new HexC());
foreach(var o in HexList){
Console.WriteLine(o.ToString());
}
}
}
控制台输出:
六角
HexC
HexC
答案 2 :(得分:0)
不像SLaks说的那样,你可以使用界面代替。例如IList<IHex>
......
答案 3 :(得分:0)
你不能施放
List<UnitC> // UnitC - to a derived from a Unit class
到
List<Unit> // Unit - the base class
尝试使用IUnit接口
答案 4 :(得分:0)
除了SLaks关于为什么你的代码不起作用的解释之外,还要考虑的一般要点是使用泛型定义了一个新类型:
Unit is a type.
UnitC is a type derived from Unit.
List<Unit> is a new type.
List<UnitC> is a new type, but is not derived from List<Unit>.
然而,
Hex[] defines multiple instances of the Hex type.
HexC[] defines multiple instances of the HexC type (which is derived from Hex).
您的赋值不起作用,因为编译器无法确保单元的元素实际上是UnitC的实例,但是如果您尝试使用逆(units = unitCs),那也不会起作用,因为List&lt ; UnitC&gt;不是从List&lt;单位&gt;。