gpt4 book ai didi

c# - 如何组织相互继承但又具有相互继承的属性的 C# 类?

转载 作者:太空狗 更新时间:2023-10-29 19:43:02 24 4
gpt4 key购买 nike

我有一个具有 Venue 概念的应用程序,事件发生的地方。 Venue有很多VenuePart秒。所以,它看起来像这样:

public abstract class Venue
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<VenuePart> VenueParts { get; set; }
}

A Venue可以是 GolfCourseVenue ,这是一个 Venue有斜率和特定类型的 VenuePart称为 HoleVenuePart :

public class GolfCourseVenue : Venue
{
public string Slope { get; set; }
public virtual ICollection<HoleVenuePart> Holes { get; set; }
}

以后可能还会有其他种类的Venue都是从Venue继承的.他们可能会添加自己的字段,并且总是有 VenuePart他们自己的特定类型。

这是 VenuePart类:

public abstract class VenuePart
{
public int Id { get; set; }
public string Name { get; set; }
public abstract string NameDescriptor { get; }
}

public class HoleVenuePart : VenuePart
{
public override string NameDescriptor { get { return "Hole"; } }
public int Yardage { get; set; }
}

我上面的声明似乎是错误的,因为现在我有一个 GolfCourseVenue有两个系列,实际上它应该只有一个。我不能覆盖它,因为类型不同,对吗?当我运行报告时,我想一般地引用这些类,我只是在这里吐出 Venue s 和 VenuePart秒。但是,当我呈现表单等时,我想具体一点。

我有很多这样的关系,我想知道我做错了什么。例如,我有一个 OrderOrderItem s,还有特定种类的Order具有特定种类的 OrderItem

更新:我应该注意到这些类是 Entity Framework 代码优先实体。我希望这无关紧要,但我想可能会。我需要以 Code-First 可以正确创建表的方式构建类。看起来 Code-First 不能处理泛型。抱歉,此实现细节妨碍了优雅的解决方案:/

更新 2:有人链接到指向 Covariance and Contravariance 的搜索,这似乎是一种将子类型中的列表限制为给定子类型本身的方法。这看起来很有希望,但是那个人删除了他们的答案!有没有人知道我可以如何利用这些概念?

更新 3:删除了子对象中的导航属性,因为它会使人感到困惑并且无助于描述问题。

最佳答案

这是使用泛型的一种可能的选择:

public abstract class VenuePart
{
public abstract string NameDescriptor { get; }
}

public class HoleVenuePart : VenuePart
{
public string NameDescriptor { get{return "I'm a hole venue"; } }
}

public class Venue<T> where T : VenuePart
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Company Company { get; set; }
public virtual ICollection<T> VenueParts { get; set; }
}

public class GolfCourseVenue : Venue<HoleVenuePart>
{
}

这里 GolfCourseVenue 有集合 VenueParts,它可以包含 HoleVenueParts 或父类(super class) HoleVenueParts。 Venue 的其他特化会将 VenuePart 限制为包含特定于该场所的 VenuePart。

第二种可能性与你所拥有的差不多

public abstract class VenuePart
{
public abstract string NameDescriptor { get; }
}

public class HoleVenuePart : VenuePart
{
public string NameDescriptor { get{return "I'm a hole venue"; } }
}

public class Venue
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Company Company { get; set; }
public virtual ICollection<VenuePart> VenueParts { get; set; }
}

public class GolfCourseVenue : Venue
{
}

现在 GolfCourseVenue 有集合 VenueParts,它可以包含 VenueParts 或父类(super class) VenueParts。在这里,Venue 的所有特化都可以包含任何类型的 VenuePart,这可能合适也可能不合适。

在回答您关于协方差的评论时,我会提出这样的建议:

public abstract class VenuePart
{
public abstract string NameDescriptor { get; }
}

public class HoleVenuePart : VenuePart
{
public override string NameDescriptor { get{return "I'm a hole venue"; } }
}

public abstract class Venue
{
public int Id { get; set; }
public string Name { get; set; }
public abstract ICollection<VenuePart> VenueParts { get; }
}

public class GolfCourseVenue : Venue
{
private ICollection<HoleVenuePart> _holeVenueParts;

public GolfCourseVenue(ICollection<HoleVenuePart> parts)
{
_holeVenueParts = parts;
}

public override ICollection<VenuePart> VenueParts
{
get
{
// Here we need to prevent clients adding
// new VenuePart to the VenueParts collection.
// They have to use Add(HoleVenuePart part).
// Unfortunately only interfaces are covariant not types.
return new ReadOnlyCollection<VenuePart>(
_holeVenueParts.OfType<VenuePart>().ToList());
}
}

public void Add(HoleVenuePart part) { _holeVenueParts.Add(part); }
}

关于c# - 如何组织相互继承但又具有相互继承的属性的 C# 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9894551/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com