c# - 你能检查一下 T 是否继承自 IEnumerable然后使用 IEnumerable 可用的方法?
问题描述
所以我正在创建一个通用方法,显然签名因此可以采用任何类型的对象。我遇到的问题是我希望用户能够将一个对象发送到我的方法,或者发送一个对象集合(我知道,与 IEnumerable 不同的接口)。现在因为 (T obj) 可能是一个对象,也可能是一个对象列表或数组,我不确定如何根据它是否是一个集合来检查和更改行为。
这就是我所拥有的,并且我收到编译器错误 CS1061,T 不包含 FirstOrDefault 的定义。这是有道理的,因为它可能没有。但据我所知,我的条件应该检查是否有。
if (typeof(IEnumerable<T>).IsAssignableFrom(obj.GetType()))
{
foreach (var info in obj.FirstOrDefault().GetType().GetProperties())
{
members.Add(info.Name, info.GetValue(obj).ToString());
}
}
else
{
foreach (var info in obj.GetType().GetProperties())
{
members.Add(info.Name, info.GetValue(obj).ToString());
}
}
如果有任何区别,成员是 Dictionary<string, string>。在这个阶段,我只是想让它同时接受集合和单个对象,我可以稍后解决这个行为。
解决方案
您必须先转换obj
为IEnumerable<T>
才能访问FirstOrDefault
. 在您的情况下,您可以使用is运算符来执行此操作。
if (obj is IEnumerable<T> e)
{
foreach (var info in e.FirstOrDefault().GetType().GetProperties))
...
}
...
您的代码照原样很好,除了您在obj
没有第一次铸造的情况下使用。例如,您可以这样做:
if (typeof(IEnumerable<T>).IsAssignableFrom(obj.GetType()))
{
var e = (IEnumerable<T>)obj;
foreach (var info in e.FirstOrDefault().GetType().GetProperties())
{
members.Add(info.Name, info.GetValue(obj).ToString());
}
...
正如您所看到的,使用is
更短且更易于阅读。
推荐阅读
- c# - 如何序列化对象以包含部分名称并连接不同的对象类型?
- python - 使用 Sympify() 将字符串转换为表达式后无法替换值
- latex - 用阿拉伯语写的乳胶文件,但参考文献列表没有用英文打印
- tensorflow - Keras-WGAN 评论家和生成器的准确度停留在 0
- verilog - Verilog 设计问题
- jquery - 自动完成返回所有值
- r - 如何在地图(ggplot)上放置比例尺和指北针?
- heroku - Heroku Hobby 层最多允许“10”个流程类型但不允许水平扩展?
- google-sheets - Google Sheets Text Join 将行合并到列中
- python - 执行 Python 代码时如何自动隐藏控制台?