从对象中提取价值的最佳实践是什么?

Which is the best practice for extracting value from object?

从对象中提取 属性 的最佳做法是什么,以便我们可以取其值?

我们有以下代码结构:

public List<Group> Activities { get; set; } 

在组中我们有:

public List<Span> Spans { get; set; }

在 Span class 中我们有:

public object Activity { get; set; }

在方法中,我有以下循环,我想从对象 Activity 属性 中获取 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
                            }
                        }
                    }
                }
            }
        }

在 span.Activity 中我们有:{ Time = 123, EndTime = 123, Points = [ -48, -49 ], PointsStart = [ 0, -2, ], TV = [ { "time": "123", "Id": 7, "TitleId": 5 } ] }

我需要从 TV 获取 ID 属性 值,稍后将其添加到列表中。 哪种做法最好,怎么做?

这可能不是最佳做法,但您可以使用反射。

您可以使用包含 GetPropertyValue() 使用反射的扩展方法的 EgonsoftHU.Extensions.Bcl nuget 包:

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();

因为 Activity inside span 是一个 unknown 并且对象类型是 unknown,我们必须使用一些东西像 REGEX 来匹配我们的值。

这是一个完美的东西。

    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;
            }
        }
    }

让我知道它是否适合你:)