您可以检查T是否继承自IEnumerable <T>,然后使用IEnumerable <T>可用的方法吗?

问题描述

所以我要创建一个通用方法,因此签名显然可以接受任何类型的对象。我遇到的问题是我希望用户能够只将一个对象发送到我的方法,或者将对象的集合(我知道,与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 。在这个阶段,我只想让它接受集合和单个对象,我以后可以解决问题。

解决方法

在访问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却更短,更易于阅读。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...