如何为T添加ObservableCollection <Class <T >>使用继承

Bri*_*anP 3 c# observablecollection

说我有以下课程:

public class BaseConfig
{
}

public class SpecialConfig : BaseConfig
{
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个通用的类定义,将包含这些:

public class ConfigList<T> : ObservableCollection<T> where T : BaseConfig
{
}
Run Code Online (Sandbox Code Playgroud)

然后我有另一个类,我想要一个ConfigList对象的集合:

public class ConfigurationManager
{
    private ObservableCollection<ConfigList<BaseConfig>> _configItems

    public ConfigurationManager()
    {
        _configItems = new ObservableCollection<ConfigList<BaseConfig>>();
    }

    public void AddConfigList(ConfigList<BaseConfig> configList)
    {
        _configItems.Add(configList);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在应用程序代码的其他地方我有这个

ConfigurationManager _manager = new ConfigurationManager();
ConfigList<SpecialConfig> _configuration = new ConfigList<SpecialConfig>();
Run Code Online (Sandbox Code Playgroud)

由于一些奇怪的原因,我认为C#会因为继承而允许以下内容,但事实并非如此.我想知道的是我如何才能完成将一个对象添加到泛型类的集合中,就像我在下面所做的那样(这肯定是人们遇到的常见问题,当然有一个简单的模式/解决方案来实现这一点):

_manager.AddConfigList(_configuration);
Run Code Online (Sandbox Code Playgroud)

cuo*_*gle 5

它不会以这种方式工作,但幸运的是,你可以利用泛型中协方差来解决这个问题,定义一个新的协方差接口:

public interface IConfigList<out T>
{
}
Run Code Online (Sandbox Code Playgroud)

所以你的ConfigList继承了这个接口:

public class ConfigList<T> : ObservableCollection<T>, IConfigList<T> 
                                  where T : BaseConfig
{
}
Run Code Online (Sandbox Code Playgroud)

而你的ConfigurationManager用途IConfigList而不是ConfigList

public class ConfigurationManager
{
    private ObservableCollection<IConfigList<BaseConfig>> _configItems;

    public ConfigurationManager()
    {
        _configItems = new ObservableCollection<IConfigList<BaseConfig>>();
    }

    public void AddConfigList(IConfigList<BaseConfig> configList)
    {
        _configItems.Add(configList);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后它会工作:

 ConfigurationManager _manager = new ConfigurationManager();
 IConfigList<BaseConfig> _configuration = new ConfigList<SpecialConfig>();

 _manager.AddConfigList(_configuration);
Run Code Online (Sandbox Code Playgroud)