如何区分子类和父类对象?

4
我正在处理两个类似于以下结构的层次结构 -
层次结构1:
public class Content
{
}

public class Text : Content
{
}

public class Image : Content
{
}

等级制度2:
public class ContentProperties
{
}

public class TextProperties : ContentProperties
{
}

public class ImageProperties : ContentProperties
{
}

现在我想实现两个行为:
首先,我想要一个ContentProperties属性的属性,这样我就可以将其推广到Content的所有子类。然后,根据所需的子类型,在子类中独立地分配它们。
像这样的东西。
public class Content
{
    public ContentProperties Properties {get;set;}
}

public class Text : Content
{
    public Text()
    {
        this.Properties = new TextProperties();
    }
}

"...等等其他子类也是如此。"
"其次,我想限制一种类型的子类只能分配相应类型的属性。"
"例如:"
Text text = new Text();
text.Properties = new ImageProperties(); //This should give an error - should not be possible.

我可以通过将单个属性保存在单独的子类中来实现第二种行为,但这将与我的第一种行为相矛盾。而且,我不想通过创建两个单独的对象来保留冗余数据。我可以使用 check-in 属性设置器或使用设置器方法来实现类似的功能,但它不会是完全相同的行为。
有人能提供建议吗?
如果标题导致任何误解,对不起。

3
你可以将 Properties 类型变成你的内容类的泛型类型,然后以泛型参数为基础构建你的类型。 - Icepickle
@Icepickle 这是解决问题的好方法,但如果我有一个内容列表,其中可能是文本或图像,并且我只想更新这些对象的ContentProperties成员,那么这不会引起问题吗? - Jasmeet
不完全是这样,当你循环时,你总是会有if (item is Text textContentItem)这样的结构,所以你总是会准确地知道你会得到什么 ;) - Icepickle
@Icepickle,没错。如果我说错了,请纠正我,但是你的实现不会删除ContentProperties层次结构的整个目的吗? - Jasmeet
我不完全理解你所说的去除目的是什么意思,难道你的目的不是为了在基类上实现一种类型安全的通用成员吗?在某个时候,你必须决定如何处理它们。我认为我对当前想法最大的问题是我有一个属性的setter,我会选择一个只设置一次的自动属性。但如果按照建议的方式做起来似乎不好,那么你需要提供更多信息,到底是什么让你感到困扰? :) - Icepickle
1个回答

4

您可以使用泛型和约束

public class Content<T> where T : ContentProperties 
{
    public T Properties {get;set;}
}

public class Text : Content<TextProperties>
{
}

public class Image : Content<ImageProperties>
{
}

我编辑了答案 - 在子类中不需要重新定义属性....

子类中的属性"Properties"将是TextPropertiesImageProperties类型。

感谢您的评论。


1
@JasmeetsinghBansal 是的, 会的。应该在派生类中声明虚拟属性,并重写其中的访问器(getter和setter),分别访问TextProperties和ImageProperties。这样,您可以从Properties属性访问基本属性,当您想要访问文本或图像特定属性时,可以访问TextProperties和ImageProperties。同时只存在一个属性实例。 - ckuri
@OfirWinegarten 只是一个疑问。如果我有一个内容列表,其中可能是文本或图像,并且我只想更新这些对象的ContentProperties成员,那么这种实现会不会引起问题? - Jasmeet
不,你总是可以这样做的。List<ContentProperties> 可以存储这两个子类。一个简单的 foreach 循环将给你 ContentProperties,而你总是可以通过使用 OfType 来选择只获取特定类型的值。 - Ofir Winegarten

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接