我正在尝试组建这样的架构:
科
[...]
然后我尝试像这样实例化这个架构:
var sections = new List<ISection>
{
new Section("Section Header", new List<Group<IItem>>
{
new SpecificGroupType1(token, "GroupName")
}
};
然后,SpecificGroupType1会旋转一个适当的IItem类型的新列表。
但是我收到了以下错误:
Argument SpecificGroupType1 is not assignable to parameter type Group<IItem>
我不太清楚为什么,因为SpecificGroupType1继承自Group。
完整的体系结构看起来像这样(我省略了IAttribute的东西,因为我遇到的问题发生在IAttribute的东西甚至涉及之前):
Section.cs
public interface ISection { // Stuff }
public class Section : ISection
{
public Section(string sectionName, IList<Group<IItem>> groups)
{
Name = sectionName;
Groups = groups;
}
}
Group.cs
public interface IGroup { // Stuff }
public abstract class Group<T> : IGroup where T : IItem
{
protected Group(JToken token, string groupName)
{
Name = groupName;
Items = new List<IItem>();
foreach (var itemToken in Token.Children())
{
Items.Add((Item)Activator.CreateInstance(typeof(T), itemToken);
}
}
public string Name { get; internal set; }
public JToken Token { get; internal set; }
protected IList<IItem> Items { get; set; }
}
SpecificGroupType1.cs
public class SpecificGroupType1 : Group<SpecificItemType1>
{
public SpecificGroupType1(JToken token, string groupName) : base(token, groupName) {}
// Stuff
}
Item.cs
public interface IItem { // Stuff }
public abstract class Item : IItem
{
protected ConfigurationItem(JToken token)
{
Attributes = new List<IAttribute>();
Token = token;
}
public IList<IAttribute> Attributes { get; set; }
public JToken Token { get; set; }
}
SpecificItemType1.cs
public class SpecificItemType1 : Item
{
public SpecificItemType1(JToken token) : base(token) {}
// Stuff
}
答案 0 :(得分:2)
从根本上说,这是您的通用参数的问题。考虑这个简化的例子。
// does not compile
Group<IItem> g = new SpecificGroupType1(token, "GroupName");
// does compile
Group<SpecificItemType1> g = new SpecificGroupType1(token, "GroupName");
问题是SpecificGroupType1
实现了类Group<SpecificItemType1>
, 与Group<IItem>
相同。如果您希望能够以这种方式使用更多派生的泛型参数类型,则需要使用协变泛型参数声明。在C#中,这只能在接口而不是类上进行,因此您可能需要重构一下。它会是这样的。
interface IGroup<out T> : IGroup where T: IItem {
// declarations
}
请注意out
关键字。