首页 > 解决方案 > 你能检查一下 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>。在这个阶段,我只是想让它同时接受集合和单个对象,我可以稍后解决这个行为。

标签: c#.nettypesienumerablesystem.reflection

解决方案


您必须先转换objIEnumerable<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更短且更易于阅读。


推荐阅读