从C#中的对象检索数据

时间:2018-01-04 22:31:01

标签: c# linq

我有一个对象(大学),其中包含列表项(校园,课程,学生等)。

public class Universities
{
    [DataMember]
    public List<Campus> CampusList { get; set; }
    [DataMember]
    public List<Course> CourseList { get; set; }
    [DataMember]
    public List<Student> StudentList { get; set; }
}

public class Campus
{
    [DataMember]
    public Guid Id { get; set; }

    [DataMember]
    public string ErrorMessage { get; set; }
}
public class Course
{
    [DataMember]
    public Guid Id { get; set; }

    [DataMember]
    public string ErrorMessage { get; set; }
}
public class Student
{
    [DataMember]
    public Guid Id { get; set; }

    [DataMember]
    public string ErrorMessage { get; set; }
}

我需要知道任何列表项是否有错误消息。

例如,我需要使用LINQ或其他替代方法捕获所有错误消息。

Universities 
   - CampusList
   - CourseList
      ErrorMessage
   - StudentList
      ErrorMessage

由于我无法编写Universities.Any()

等查询

我无法编写for循环,因为对象没有Count扩展名,例如Universities.Count

我可以访问每个列表项Universities.StudentsUniversities.Courses等等。

任何指南或建议?

1 个答案:

答案 0 :(得分:2)

所以正确的方法是创建一个接口来反映包含ErrorMessage属性的对象的通用性:

interface IErrorMessage {
    string ErrorMessage { get; set; }
}

然后在每个对象上实现接口:

public class Campus : IErrorMessage {
    [DataMember]
    public Guid Id { get; set; }
    [DataMember]
    public string ErrorMessage { get; set; }
}

然后,您可以添加私有帮助器方法和公共方法,以将ErrorMessage返回到Universities类:

private List<string> GetErrorMessagesFromList<T>(List<T> aList) where T : IErrorMessage {
    return aList.Where(x => !String.IsNullOrEmpty(x.ErrorMessage)).Select(x => x.ErrorMessage).ToList();
}

public List<string> GetErrorMessages() {
    return GetErrorMessagesFromList(CampusList)
            .Concat(GetErrorMessagesFromList(CourseList))
            .Concat(GetErrorMessagesFromList(StudentList))
            .ToList();
}

然后,给定Universities个对象,您可以调用GetErrorMessages

但是,您也可以在运行时使用反射并提取所有内容,这很难遵循,复杂且无疑会更慢,但可以通过向Universities类添加方法来完成:

public List<string> GetErrorMessagesByReflection() {
    bool IsList(Type aType) => aType.IsGenericType && aType.GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>));

    var errorMessages = new List<string>();

    var props = this.GetType().GetProperties()
                    .Where(p => IsList(p.PropertyType));

    foreach (var prop in props) {
        var aList = prop.GetValue(this) as IEnumerable;
        foreach (var anItem in aList) {
            var possibleErrorMessage = anItem.GetType().GetProperty("ErrorMessage").GetValue(anItem) as string;
            if (!String.IsNullOrEmpty(possibleErrorMessage))
                errorMessages.Add(possibleErrorMessage);
        }
    }

    return errorMessages;
}