是否可以从基础对象的List访问子对象属性?

时间:2015-07-13 20:38:18

标签: c# inheritance properties

我有一个基本的Message对象,然后是从Message对象继承的许多更具体的Message对象。我希望能够将一些消息存储到列表列表中。我需要能够找到外部List的索引,其中存在具有特定属性值的特定子消息。 (对于我的特定项目,我将消息添加到List的顺序始终相同,因此我将知道哪个消息在哪个索引处。)

namespace Project
{
    public class Message {} //base class
}

以下是两个示例子消息:

class ABCMessage : Message
{
    public ABCMessage() { }

    public string ABCproperty1 { get; set; }
    public string ABCProperty2 { get; set; }
    public string ABCProperty3 { get; set; }
}


class XYZMessage : Message
{
    public XYZMessage() { }

    public string XYZproperty1 { get; set; }
    public string XYZProperty2 { get; set; }
}

这就是我想要做的事情:

public static List<List<Message>> MessageList;

ABCMessage abcMessage = new ABCMessage();
abcMessage.ABCProperty1 = 1;
abcMessage.ABCProperty2 = 2;
abcMessage.ABCProperty3 = 3;
List<Message> myList = new List<Message>();
myList.Add(abcMessage);

//...

int index;
for (int i = 0; i < MessageList.Count; i++) {
    if (MessageList[i][0].ABCProperty2 == 5) {
        index = i;
        break;
    }
}

然而,问题是我无法调用该属性(或任何属性)。有谁知道如何解决这个问题?也许我需要在我的Message类中放置属性? (我想继承的唯一原因是为了更容易制作列表列表。)

1 个答案:

答案 0 :(得分:3)

解决方案是将每条消息转发到ABCMessage,然后,如果不为空,则它是ABCMessage的实例,因此可以测试它的属性:

int index;
for (int i = 0; i < MessageList.Count; i++) 
{
    var message = MessageList[i][0] as ABCMessage;
    if (message != null && message.ABCProperty2 == 5) 
    {
        index = i;
        break;
    }
}

由于不是每个人都喜欢as / test for null方法,另一种选择是使用is

for (int i = 0; i < MessageList.Count; i++) 
{
    var message = MessageList[i][0] as ABCMessage;
    if (MessageList[i][0] is ABCMessage && (ABCMessage)(MessageList[i][0]).ABCProperty2 == 5) 
    {
        index = i;
        break;
    }
}

但是,从C#6开始,存在一个新选项(null-conditional operator或&#34; Elvis运算符&#34;因为它也是已知的),它使用两者中最好的:< / p>

for (int i = 0; i < MessageList.Count; i++)
{
    var message = MessageList[i][0] as ABCMessage;
    if (message?.ABCProperty2 == 5)
    {
        index = i;
        break;
    }
}

如果message?.ABCProperty2 == 5不为空,则ABCProperty2语法仅测试message,从而无需进行!= null测试。