C#:<t>的列表<derived from =“”t =“”>列表</derived> </t>

时间:2011-07-10 14:01:27

标签: c#

我有一个基类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>,但我可以将数组设置为数组

5 个答案:

答案 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;。