Reputation: 131
Which is the best practice for extracting property from object ,so that we can take its value?
We have the following code structure:
public List<Group> Activities { get; set; }
In Group we have:
public List<Span> Spans { get; set; }
In Span class we have:
public object Activity { get; set; }
In method I have the following loop that I want to take from object Activity property Id from TV:
foreach (var activity in result.Activities)
{
if (activity.Spans != null)
{
foreach (var span in activity.Spans)
{
if (span.Activity != null)
{
foreach (var propertyInfo in typeof(Spans).GetProperties())
{
if (propertyInfo.Name == "Activity")
{
//take value from activity
}
}
}
}
}
}
In span.Activity we have : { Time = 123, EndTime = 123, Points = [ -48, -49 ], PointsStart = [ 0, -2, ], TV = [ { "time": "123", "Id": 7, "TitleId": 5 } ] }
I need to take from TV the Id property value and add it later to a list. Which is the best practice to do it and how?
Upvotes: 1
Views: 137
Reputation: 642
Since Activity inside span is an unknown and the object type is unknown, we'll have to use something like REGEX to match our values.
Here's something that works perfectly.
var regexPatternToGetIdAndNumber = "\"([Id]+?)\"\\s*:\\s*\\d+";
var regexPatternToGetNumber = "\\d+";
foreach (var activity in activities.Where(a => a.Spans != null))
{
foreach (var span in activity.Spans)
{
foreach (var propertyInfo in span.GetType()
.GetProperties()
.Where(property => property.Name == "Activity"))//Get Properties of Span Names "Activity"
{
var stringValue = propertyInfo.GetValue(span)?.ToString();
if (string.IsNullOrEmpty(stringValue))
{
continue; //If Value is empty, Skip it and continue
}
var idAndValueString = Regex.Match(stringValue, regexPatternToGetIdAndNumber).ToString(); //Returns "Id": 7
var idValue = Regex.Match(idAndValueString, regexPatternToGetNumber).ToString(); //Returns 7;
}
}
}
Let me know if it works for you :)
Upvotes: 2
Reputation: 3256
It may not be the best practise but you can use reflection.
You can use the EgonsoftHU.Extensions.Bcl nuget package that contains a GetPropertyValue()
extension method that uses reflection:
using System.Linq;
using EgonsoftHU.Extensions.Bcl;
// Get all id values
var ids =
result
.Activities
.SelectMany(activity => activity.Spans)
.Where(spans => spans != null)
.Select(span => span.Activity)
.Where(activity => activity != null)
.Select(
activity =>
{
object tv = activity.GetPropertyValue("TV");
object rawId = null;
if (tv is IEnumerable e)
{
rawId = e.Cast<object>().FirstOrDefault()?.GetPropertyValue("Id");
}
return rawId is int id ? (int?)id : (int?)null;
}
)
.Where(id => id != null)
.Cast<int>()
.ToList();
Upvotes: 2