【问题标题】:How to determine if an object is a collection of objects implementing a common interface如何确定一个对象是否是实现公共接口的对象的集合
【发布时间】:2010-08-19 20:02:14
【问题描述】:

当 PropertyInfo 实例引用作为 IDataExtractor 对象集合的对象时,我有以下方法返回 true:

    private bool IsCollectionOfIDataExtractors( PropertyInfo propInfo )
    {
        var result = false;

        var extractors = propInfo.GetValue(dataExtractor, null);

        if (typeof ( ICollection ).IsAssignableFrom(extractors.GetType() ) ||
            typeof ( ICollection<> ).IsAssignableFrom(extractors.GetType() ) )
        {

            IEnumerator extractor = ((ICollection)extractors).GetEnumerator();

            extractor.MoveNext();

            if (typeof ( IDataExtractor ).IsAssignableFrom(
                extractor.Current.GetType()) )
            {
                result = true;
            }
        }

        return result;
    }

在考虑这个方法时,我通过 StackOverflow 搜索,发现以下相关项 Accessing a Collection Through Reflection 。这让我成功了一半。

经过一些测试,它看起来很有效,但我不是 100% 相信的。我正在做更强大的测试。

我很好奇,有没有更好的方法来实现这个方法?我真的不喜欢演员表,

IEnumerator extractor = ((ICollection)extractors).GetEnumerator();

【问题讨论】:

  • 你不喜欢演员阵容的哪一点?
  • 如果我能帮上忙,我总是尽量不投。我意识到在 if 我已经检查了分配能力的正文中。但我不确定 typeof(ICollection) 是否为真,那么演员阵容是否有效?
  • 我现在正在添加测试来验证这一切。我更普遍的问题是我真正感兴趣的是,有没有人知道实现此方法的更好方法?
  • 是的。 ICollection&lt;&gt; 实现了ICollection,所以转换不会失败。但如果是我,我会做一个'as'演员并测试null。我也可能会测试/转换IEnumerable 而不是ICollection,除非您需要关于ICollection 接口的一些非常具体的内容。
  • @Toby, ICollection&lt;T&gt; 不保证ICollection 的实现。 BCL 集合实现了两者,但自定义集合可能实现也可能不实现。

标签: c# .net


【解决方案1】:
var extractors = propInfo.GetValue(dataExtractor, null);
var asEnumerable = extractors as IEnumerable;

if (asEnumerable != null)
{
    var enumerator = asEnumerable.GetEnumerator();
    enumerator.MoveNext();

    if (enumerator.Current != null)
        return enumerator.Current is IDataExtractor;
}

return false;

【讨论】:

  • 我在写这篇文章的时候突然想到,如果集合是空的,你将很难确定它的成员类型,并且你的原始代码会抛出一个NullReferenceExceptionextractor.Current.GetType()
  • 谢谢,这减少了我的代码大小并使其更易于理解。谢谢托比。
  • 请注意,并非所有实现ICollection&lt;T&gt; 的对象都必须实现ICollectionIList&lt;T&gt;IList 也是如此。
  • 我已经使用 IEnumerable 而不是 ICollection 重写了,因为 ICollection 和 ICollection 都实现了它。
  • @Dan:哦,你是对的。我已经习惯了看到它们并排实现,以至于在我的脑海中,ICollection 是一个“继承”的接口。
猜你喜欢
  • 2018-11-17
  • 1970-01-01
  • 1970-01-01
  • 2012-12-29
  • 2015-03-17
  • 2010-11-24
  • 2010-10-20
  • 2010-10-31
相关资源
最近更新 更多