将泛型对象添加到泛型集合时编译时间错误 [英] Compile time error when adding generic object to collection of generics

查看:123
本文介绍了将泛型对象添加到泛型集合时编译时间错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

SHORT:
我们有一个通用接口和一个泛型集合接口。尝试将通用接口的实现添加到集合失败。发生什么是我得到一个编译时异常,说:


无法从TestApp.IState< T>转换到TestApp.IState< TestApp .IView>'


LONG [代码示例]:

  class Program 
{
static void Main(string [] args)
{
var coll = new StateCollection();
var state = new SomeState();
coll.AddState(state);
}
}

public class StateCollection
{
private List< StateBase< IView>> _states = new List< StateBase< IView>>();

public void AddState< T>(StateBase< T> state)其中T:IView
{
_states.Add(state);
}
}

公共类SomeState:StateBase< SomeView>
{

public IView查看
{
get;



public class SomeView:IView
{
}

公共抽象类StateBase< T>其中T:IView
{
private SomeView _view;
public SomeView View
{
get {return _view; }
}
}

public interface IView
{
}

为什么会发生这种情况?在AddState中,我们提到T必须是IState的一个实例。有人可以帮我们解释为什么会发生这种情况,以及如何做我们想做的事情?

编辑1:
我们也试过:

  public void AddState(IState< IView> state)
{
_states.Add(state);
}

但是,这只是将编译时错误移动到'coll.AddState(state) '
所以同样的事情发生在另一个地方。



编辑2:
问题!我没有给出正确的例子。出IState不是一个接口,而是一个抽象类。非常抱歉!改变了使用抽象类的代码

解决方案

这看起来更像是Add函数的参数错误。您是否尝试过不使用泛型来声明添加函数?继承本身应该允许它。使AddState函数看起来像这样:



编辑(按照Edit2):

如前所述,继承本身应该照顾泛型。只要你正确声明的任何类实现了 IView IState< IView> ,那么就不应该有任何...

pre $ public absract class StateBase
{
public IView view {get;组; }

....
}

public Interface IView
{...}

public class StateCollection
{
私人列表< StateBase> _states = new List< StateBase>();

public void AddState(StateBase state)
{
_states.Add(state);
}
}

公共类SomeView:IView
{...}

等等等等等等,经常需要

  public class SomeState:StateBase 
{
private SomeView my_view;

public IView view
{
get {return(IView)SomeView; }
set {; }
}
}

//程序保持不变



在这种情况下,SomeState仍然是一个IState对象,并且所有的IState对象都实现了IView,而SomeView则是一个IView对象。 SomeState在内部实现SomeView。对我来说看起来是一样的,但我不知道自适应会如何与您的真实代码一起工作。



其他任何类都遵循相同的模型。纽约州将实施StateBase,并在内部宣布一个自定义View,它本身需要扩展IView。如此一来,自定义视图上的IView广告就会生效。



从评论

  public class BarState:StateBase 
{
private BarView my_view;

public IView view
{
get {return(IView)BarView; }
set {; }
}
}

public class BarView:IView
{...}


we've reached a point where we have no clue how to continue:

SHORT: We have a generic interface and a collection of the generic interface. Trying to add an implementation of the generic interface to the collection fails. What happens is that I get a compile time exception saying:

cannot convert from TestApp.IState<T>' to TestApp.IState<TestApp.IView>'

LONG [Code example]:

class Program
{
    static void Main(string[] args)
    {
        var coll = new StateCollection();
        var state = new SomeState();
        coll.AddState(state);
    }
}

public class StateCollection
{
    private List<StateBase<IView>> _states = new List<StateBase<IView>>();

    public void AddState<T>(StateBase<T> state) where T: IView
    {
        _states.Add(state);
    }
}

public class SomeState : StateBase<SomeView>
{

    public IView View
    {
        get;
    }
}

public class SomeView : IView
{
}

public abstract class StateBase<T> where T : IView
{
    private SomeView _view;
    public SomeView View
    {
        get { return _view; }
    }
}

public interface IView
{
}

Why does this happen? In the AddState we mention that T has to be an instance of IState. Could someone help us out with why this happens and how to do what we want to do?

EDIT1: We also tried:

    public void AddState(IState<IView> state)
    {
        _states.Add(state);
    }

But that just moves the compile time error to 'coll.AddState(state)' So the same thing happens in another place.

EDIT2: PROBLEM! I didn't give the right example. Out IState is not an interface but an abstract class. Very sorry for that! Changed code to use abstract class

解决方案

this looks more like a parameter error for the Add function. Have you tried declaring the add function without using the generics? The inheritance itself should allow it. Make the AddState function look like like so:

Edit (as per Edit2):

As mentioned, the inheritance itself should take care of the generics. As long as whatever class you declared properly implements IView, or IState<IView>, then there shouldn't be any issues...

public absract class StateBase
{
    public IView view { get; set; }

    ....
}

public Interface IView
{ ... }

public class StateCollection
{
    private List<StateBase> _states = new List<StateBase>();

    public void AddState(StateBase state)
    {
        _states.Add(state);
    }
}

public class SomeView : IView
{ ... }

etc etc and so on, as often as needed

public class SomeState : StateBase
{
    private SomeView my_view;

    public IView view
    {
        get { return (IView)SomeView; }
        set { ; }
    }
}

//program remains unchanged

In this case, SomeState is still an IState object, and all IState objects implement IView, and SomeView is an IView object. SomeState implements SomeView internally. Looks the same to me, but I dont know how well the adaption would work with your real code.

Any other classes would follow the same model. The State will implement StateBase, and internally declare a custom View, which itself needs to extend IView. That way the IView cast on the custom view will work.

From comment:

public class BarState : StateBase
{
    private BarView my_view;

    public IView view
    {
        get { return (IView)BarView; }
        set { ; }
    }
}

public class BarView : IView
{ ... }

这篇关于将泛型对象添加到泛型集合时编译时间错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆