我得到了ContainerA
,ContainerB
,ElementA
和ElementB
类。除了可以添加接口之外,由于原因很好我无法修改这些类。
我想要的是类似IElements
的界面(期望合法),因为它可以让我轻松地遍历元素并从ContainerA
或{{1}的元素中读取属性而不知道实际使用了哪个具体实现。在任何类上都没有方法。对于元素类,我只需要访问ContainerB
实现的属性,例如ElementA
属性。
我有什么选择?
Id
我希望达到类似的目的
public interface IElements
{
List<ElementA> Elements { get; set; }
}
public class ContainerA : IElements
{
public List<ElementA> Elements { get; set; }
}
public class ContainerB : IElements
{
public List<ElementB> Elements { get; set; }
}
public class ElementA
{
public string Id { get; set; }
}
public class ElementB : ElementA
{
}
答案 0 :(得分:1)
有很多方法可以切成薄片,但是我会考虑在此处使用具有约束的泛型。我还将考虑元素对象的接口(或抽象基类),例如:
public interface IElement
{
int Id { get; set; }
}
您的通用元素界面将如下所示:
public interface IElements<TElement>
where TElement : ElementA
{
List<TElement> Elements { get; set; }
}
使容器类看起来像这样:
public class ContainerA : IElements<ElementA>
{
public List<ElementA> Elements { get; set; }
}
public class ContainerB : IElements<ElementB>
{
public List<ElementB> Elements { get; set; }
}
现在,您可以访问实现您的接口的任何对象的Id
属性,例如:
public void DoFoo<TElement>(IElements<TElement> elements)
where TElement : ElementA
{
foreach (var element in elements.Elements)
{
// This will compile fine
var id = element.Id;
}
}
答案 1 :(得分:1)
IEnumerable
是covariant,即IEnumerable<SubtypeOfT>
是IEnumerable<T>
的子类型。因此,以下应该起作用:
public interface IElements
{
IEnumerable<ElementA> ReadOnlyElements { get; }
}
public class ContainerA : IElements
{
public List<ElementA> Elements { get; set; }
IEnumerable<ElementA> IElements.ReadOnlyElements => Elements;
}
public class ContainerB : IElements
{
public List<ElementB> Elements { get; set; }
IEnumerable<ElementA> IElements.ReadOnlyElements => Elements;
}
您可以按以下步骤遍历它们:
IElements container = ...;
foreach (var element in container.ReadOnlyElements)
{
Console.WriteLine(element.Id);
}