【问题标题】:Cast a property to its actual type dynamically using reflection (where actual type is generic) v2使用反射将属性动态转换为实际类型(其中实际类型是通用的)v2
【发布时间】:2020-10-23 06:25:57
【问题描述】:

这是我在here 之前提出的问题的略微修改版本。

实际位置如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace cns01
{
    class Program
    {
        public class DataFieldInfo2<T>
        {
            public bool IsSearchValue { get; set; } = false;
            public T Value { get; set; }
        }

        public class SmartRowVertrag
        {
            public DataFieldInfo2<int> ID { get; set; }
            public DataFieldInfo2<string> VSNR { get; set; }
        }

        static void Main(string[] args)
        {
            SmartRowVertrag tester = new SmartRowVertrag();
            tester.ID = new DataFieldInfo2<int>() { Value = 777, IsSearchValue = false };
            tester.VSNR = new DataFieldInfo2<string>() { Value = "234234234", IsSearchValue = true };

            var g = RetData3(tester);
        }

        public static object RetData3(object fsr)
        {
            object retVal = new object();
            var props = fsr.GetType().GetProperties();
            foreach (var prop in props)
            {
                PropertyInfo propInfo = prop.GetType().GetProperty("IsSearchValue"); // <-- here I get null
                propInfo = prop.PropertyType.GetProperty("IsSearchValue"); // here I get a propertyInfo, but...
                dynamic property = propInfo.GetValue(fsr, null); // ...<-- here fires error
                var result = property.IsSearchValue;
                if (result == true)
                {
                    // doThis
                }
            }
            return retVal;
        }
    }
}

我确实需要获取存储在IsSearchValue 中的布尔值来完成任务。

先谢谢了。

我非常感谢任何有帮助的答案。

【问题讨论】:

  • "here fires error" 并不能很好地说明使用情况。请在帖子中使用堆栈跟踪指定错误。 (很高兴有一个完整的例子 - 谢谢。)

标签: c# generics casting propertyinfo


【解决方案1】:

fsrSmartRowVertrag。您正试图从中获取 IsSearchValue - 但它不存在。

相反,您需要调用GetValue 两次——一次在prop 上,传入fsr(因此相当于使用fsr.IDdsr.VSNR),然后在propInfo 上调用一次在第一次调用的结果中。

接下来,您的dynamic 使用尝试在propInfo.GetValue() 的结果上获得IsSearchValue - 您正在尝试有效地评估something.IsSearchValue.IsSearchValue

这是该部分的更正代码:

public static object RetData3(object fsr)
{
    object retVal = new object();
    var props = fsr.GetType().GetProperties();
    foreach (var prop in props)
    {
        PropertyInfo propInfo = prop.PropertyType.GetProperty("IsSearchValue");
        if (propInfo != null)
        {
            object fieldInfo = prop.GetValue(fsr);
            object isSearchValue = propInfo.GetValue(fieldInfo);
            if (isSearchValue.Equals(true))
            {
                Console.WriteLine($"{prop.Name} has a searchable field");
            }
        }
    }
    return retVal;
}

如果您有 DataFieldInfo2&lt;T&gt; 实现的非泛型接口或基类,则可以避免使用两次反射。例如:

public interface IDataFieldInfo
{
    bool IsSearchValue { get; }
}

public class DataFieldInfo2<T> : IDataFieldInfo
{
    ...
}

然后你可以让你的反射代码更清晰:

public static object RetData3(object fsr)
{
    var fieldProperties = fsr.GetType().GetProperties()
        .Where(prop => typeof(IDataFieldInfo).IsAssignableFrom(prop.PropertyType));
    foreach (var fieldProperty in fieldProperties)
    {
        var field = (IDataFieldInfo) fieldProperty.GetValue(fsr);
        if (field.IsSearchValue)
        {
            Console.WriteLine($"{fieldProperty.Name} is a search value field");
        }
    }
    
    // We don't actually know what you're trying to return
    return null;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 2012-08-27
    • 1970-01-01
    • 2011-06-10
    相关资源
    最近更新 更多