c# - 通过反射动态修改 IEnumerable 属性
问题描述
我有各种各样的类,它们具有实现的各种属性IEnumerable
(例如IEnumerable<string>
,、、IEnumerable<bool>
等IEnumerable<enum>
)。我正在尝试编写一些代码来过滤这些属性的值(例如,如果值是{ "one", "two", "three" }
我可能想要过滤 where .Contains("t")
)。
这是我所拥有的精髓:
class MyObject
{
public IEnumerable<string> stringProp { get; set; } = new[] { "one", "two", "three" };
public IEnumerable<bool> boolProp { get; set; } = new[] { true, false, true };
public IEnumerable<int> intProp { get; set; } = new[] { 1, 2, 3 };
}
public static void Main(string[] args)
{
MyObject obj = new MyObject();
foreach (PropertyInfo prop in typeof(MyObject).GetProperties())
{
prop.SetValue(obj, (prop.GetValue(obj) as IEnumerable<dynamic>).Where(val => val != null));
}
}
问题是,当我尝试将值设置回对象 ( property.SetValue
) 时,会引发错误,因为新值是IEnumerable<object>
.
Object of type 'System.Linq.Enumerable+WhereArrayIterator`1[System.Object]' cannot be converted to type 'System.Collections.Generic.IEnumerable`1[System.String]'
我已经尝试过Convert.ChangeType
,但这不起作用,因为IEnumerable
没有实现IConvertible
.
我怎么能做到这一点?为什么 LINQWhere
查询会更改IEnumerable<dynamic>
into IEnumerable<object>
?
解决方案
我理解正确吗?你在寻找这样的东西吗?
var obj = new MyObject();
foreach (var prop in typeof(MyObject).GetProperties())
{
//assumming all things are IEnumerable<something>
var type = prop.PropertyType.GenericTypeArguments[0];
//We can't "instantiate" something as ephemeral as an IEnumerable,
//so we need something more concrete like a List
//There might be other ways to filter - this seemed to be the easiest
var listType = typeof(List<>).MakeGenericType(type);
var instance = (IList)Activator.CreateInstance(listType);
var currentEnum = (IEnumerable)prop.GetValue(obj);
foreach (var item in currentEnum)
{
if (item != default) // != null would be silly for booleans and ints
{
instance.Add(item);
}
}
prop.SetValue(obj, instance);
}
总结:泛型和动态关键字通常不会以这种方式混合使用——动态泛型参数没有任何意义。将动态视为实际上意味着“对象”的东西,但也可以让你写任何你喜欢的东西。当然,IEnumerable<object> 可能更适合作为 IEnumerable。对于具有多个参数的泛型,您最好使用对象甚至更好的特定类。
推荐阅读
- python - 我得到了这个结果(对于我,枚举中的标签(train_paths):NameError:名称'train_paths'未定义进程完成退出代码1)
- r - 交互图纵向数据ggplot
- debugging - 在 windbg 中,什么会导致消息“警告:无法验证 mydll.dll 的校验和”?
- python-3.x - Django admin - 用户和组扩展
- gitlab - 运行管道上的“缺少 CI 配置文件”消息,但存在 .gitlab-ci.yml
- flutter - 升级 Flutter 版本后运行 pod install 时出现 Flutter 错误
- wordpress - GTranslate wordpress 登录不适用于其他语言
- angular - 使用 Webpack for Angular 构建的构建中缺少 :host {} css
- jenkins - 如何在`AsyncResourceDisposer.doStopTracking()`中使用`StaplerResponse rsp`
- javascript - Angular:TypeError:未定义不是对象(评估'navigator.permission.query')