无法在C#中将实现接口的类的实例添加到所述接口的List中

时间:2012-09-06 23:17:55

标签: c# generics interface

我有这个错误:

  

无法隐式转换类型   'System.Collections.Generic.List'到   'System.Collections.Generic.List'

对于以下代码:

当我尝试添加到列表中时:

if (information != null) // not empty
{
    foreach (CharacterInformation info in information)
    {
        chButtons.Add(new GuiSelectCharacterButton(
            selectGui,
            new Rectangle(100, 100, 450, 100)
        ));
        chButtons[chButtons.Count - 1].ImageTexture = GUISprites.Instance().GetTexture(UITexture.RainbowDash);
        chButtons[chButtons.Count - 1].Texture = GUISprites.Instance().GetTexture(UITexture.CommonButtonNotPressed);
        chButtons[chButtons.Count - 1].PressedTexture = GUISprites.Instance().GetTexture(UITexture.CommonButtonPressed);
        chButtons[chButtons.Count - 1].ImageTextureWidth = 90;
        chButtons[chButtons.Count - 1].ImageTextureHeight = 90;
        chButtons[chButtons.Count - 1].ButtonPressed += LoginCharacterHandler;
        chButtons[chButtons.Count - 1].Font = GameFonts.Instance().GetSpriteFont(FontType.UI);
        chButtons[chButtons.Count - 1].Information = information[chButtons.Count - 1];
    }
}
// error at this line
buttoncontainer.ButtonList = chButtons;

班级声明:

public class GuiSelectCharacterButton : GUIImageButton, IGameUserInterfaceImageButton
{
    public GuiSelectCharacterButton(GUI parent, Rectangle area)
        : base(parent, area)
    {

    }
}

接口:

public interface IGameUserInterfaceImageButton : IGameUserInterfaceComponent
{
    bool InsideContainer { get; set; }
    Rectangle InsideContainerArea { get; set; }
}

IGameUserInterfaceImageButton列表:

private List<IGameUserInterfaceImageButton> buttonList;

public List<IGameUserInterfaceImageButton> ButtonList
{
    get
    {
        return buttonList;
    }
    set
    {
        buttonList = value;
        scrollbarThumbTotalHeight = marginButtons;
        scrollbarThumbY = 0;
        int yhelper = 0;
        foreach (IGameUserInterfaceImageButton button in buttonList)
        {
            yhelper += marginButtons;
            button.InsideContainer = true;
            button.InsideContainerArea = new Rectangle(
                marginXbutton,
                yhelper,
                button.Area.Width,
                button.Area.Height
            );
            yhelper += marginButtons + button.Area.Height;
            scrollbarThumbTotalHeight += button.Area.Height + marginButtons * 2;
        }
        scrollbarThumbDrawHeight = 0;
        if (scrollbarThumbTotalHeight > Area.Height)
        {
            scrollbarThumbDrawHeight = (int)Math.Pow(AreaScrollbar.Height, 2) / scrollbarThumbTotalHeight;
        }
    }
}

我不知道我的错误在哪里。基类(GUIImageButton)实现所述接口的所有内容。我在我的程序的其他部分做了这个,但出于任何奇怪的原因,它在这里不起作用。

2 个答案:

答案 0 :(得分:1)

简答:

如果我们有一个接口和一个实现它的类:

public interface IFoo { }
public class Foo : IFoo { }

有效:

var x = new List<Foo>();
x.Add(new Foo());
var y = new List<IFoo>();
y = x;

工作:

var x = new List<IFoo>();
x.Add(new Foo());
var y = new List<IFoo>();
y = x;

说明

您的问题不在于尝试将实例添加到列表中; chButtons.Add()方法工作正常。

您尝试将chButtons分配给buttoncontainer.ButtonList时遇到问题。这两个标识符的类型不同。您已经说过ButtonList的类型,但您还没有说chButtons是什么。

如果我怀疑chButtonsList<GuiSelectCharacterButton>,那么你所做的就是行不通。即使List<Foo>,您也无法将List<IFoo>分配给Foo : IFoo;这称为“协方差”,C#不支持具体类。

如果您将chButtons定义为与ButtonList具有完全相同的类型,例如一个List<IGameUserInterfaceImageButton>,那么你的代码应该可以正常工作。

答案 1 :(得分:1)

List<A>List<IA>继承时,您无法直接从A转换为IA个事件。

您可以做的是chButtons类型IGameUserInterfaceImageButton。然后在添加它们时将每个项目转换为界面:

var chButtons = new List<IGameUserInterfaceImageButton>();
chButtons.Add(
    (IGameUserInterfaceImageButton)new GuiSelectCharacterButton(
        // etc ...
    )
);
// this is now valid
buttoncontainer.ButtonList = chButtons