简体   繁体   中英

Using C# Reflection, how to get Object's properties and their values if that Object is a property of Object that is inside of the List

I need to grab the value of a property of an ObjectB, which is a Property of ObjectA and ObjectA is inside of a List<ObjectA>

I browsed through some examplse, but could not find exactly what I need.

Here is what I'm looking for:

I have a class MyScreenClass , that has a List<TicketReportPropertyEntity> :

public class MyScreenClass
{
     public List<TicketReportPropertyEntity> TicketReportPropertyEntities{ get; set; } 
}

This is TicketReportPropertyEntity class that has another class which property I need to work with:

public class TicketReportPropertyEntity
{
    public decimal Amount{get;set;}
    public ReportPropertyEntity ReportProperty {get;set;}
} 

This is ReportPropertyEntity class:

public class ReportPropertyEntity
{
    public string PropertyName { get; set; }
}

What I need to do, is for each TicketReportPropertyEntity to get Amount from TicketReportPropertyEntity and PropertyName from ReportPropertyEntity .

The purpose is I need to compare the PropertyName with a given property and set the value to an Amount

So far, I only came up with the following:

foreach (var ticketReportEntity in mol.TicketReportPropertyEntities)
{
   PropertyInfo propertyInfo1 = ticketReportEntity.GetType().GetProperty("ReportProperty");
           //here I need to do all the logic
}

What is the solution?

If you have to work with this two properties, and you have to store it in order to work with it, you could use:

List<TicketReportPropertyEntity> list = mol.TicketReportPropertyEntities;
List<keyValuePair<string, decimal>> values = 
   list.ToDictionary(element => element.ReportProperty.PropertyName, element => element.Amout).ToList();

Then, you will have a relationship between Amout and PropertyName properties.

To do this you would have to get the child PropertyInfo of ReportPropertyEntity.PropertyName also. Then, proceed to check it against your target and set to amount to what you need.

MyScreenClass mol = new MyScreenClass{ TicketReportPropertyEntities = new List<TicketReportPropertyEntity>()};
mol.TicketReportPropertyEntities.Add(new TicketReportPropertyEntity
{
    ReportProperty = new ReportPropertyEntity
    {
        PropertyName = "CoolPropertyName"
    }
});

string propertyToSearchFor = "CoolPropertyName";

foreach (var ticketReportEntity in mol.TicketReportPropertyEntities)
{
    var type = ticketReportEntity.GetType();

    //Get PropertyInfo objects
    PropertyInfo reportProperty = type.GetProperty("ReportProperty");
    PropertyInfo reportPropertyName = typeof(ReportPropertyEntity).GetProperty("PropertyName");
    PropertyInfo amountProperty = type.GetProperty("Amount");

    //Get needed values
    ReportPropertyEntity reportPropertyValue = (ReportPropertyEntity)reportProperty.GetValue(ticketReportEntity);
    string reportPropertyNameValue = (string)reportPropertyName.GetValue(reportPropertyValue);

    //Check if change is required
    if (reportPropertyNameValue == propertyToSearchFor)
    {
        amountProperty.SetValue(ticketReportEntity, 123.45M);
    }


}
// get PropertyName from ReportPropertyEntity, and find it on TicketReportPropertyEntity
var myScreen = new MyScreenClass()
{
    TicketReportPropertyEntities = new List<UserQuery.TicketReportPropertyEntity>
    {
        new TicketReportPropertyEntity{
            Amount=1.0m,
            ReportProperty = new ReportPropertyEntity{PropertyName="Name"}
        }
    }

};
var reportPropertyAccessor = typeof(TicketReportPropertyEntity).GetProperty(nameof(TicketReportPropertyEntity.ReportProperty));
var propertyNameAccessor = typeof(ReportPropertyEntity).GetProperty(nameof(ReportPropertyEntity.PropertyName));
var amountAccessor = typeof(TicketReportPropertyEntity).GetProperty(nameof(TicketReportPropertyEntity.Amount));
typeof(TicketReportPropertyEntity).GetProperties().Dump();

foreach(object ticketReportEntity in myScreen.TicketReportPropertyEntities){
    var ticketReportPropertyEntity=reportPropertyAccessor.GetValue(ticketReportEntity);
    var pn = propertyNameAccessor.GetValue(ticketReportPropertyEntity);
    if("Name" == (string)pn){
        ticketReportPropertyEntity.Dump();
        amountAccessor.SetValue(ticketReportEntity,2.0m);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM