使用反射动态地将 属性 转换为其实际类型(其中实际类型是通用的)v2
Cast a property to its actual type dynamically using reflection (where actual type is generic) v2
这是我之前提出的问题的略微修改版本 。
实际位置如下:
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
中的布尔值才能完成任务。
先谢谢了。
非常感谢任何有帮助的回答。
fsr
就是SmartRowVertrag
。您正试图从中获取 IsSearchValue
- 但它不存在。
相反,您需要调用 GetValue
两次 - 在 prop
上调用一次,传入 fsr
(因此相当于使用 fsr.ID
或 dsr.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<T>
实现的 non-generic 接口,或者一个基础 class,你可以避免使用反射两次。例如:
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;
}
这是我之前提出的问题的略微修改版本
实际位置如下:
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
中的布尔值才能完成任务。
先谢谢了。
非常感谢任何有帮助的回答。
fsr
就是SmartRowVertrag
。您正试图从中获取 IsSearchValue
- 但它不存在。
相反,您需要调用 GetValue
两次 - 在 prop
上调用一次,传入 fsr
(因此相当于使用 fsr.ID
或 dsr.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<T>
实现的 non-generic 接口,或者一个基础 class,你可以避免使用反射两次。例如:
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;
}