【问题标题】:How can LINQ actions be performed on a CollectionBase?如何在 CollectionBase 上执行 LINQ 操作?
【发布时间】:2015-08-06 10:01:13
【问题描述】:

我正在编写一个 C# 表单应用程序,并且我有一个 PropertyGrid 控件的以下集合:

public class CustomWebpageJavaScriptFunctionCollection : CollectionBase, ICustomTypeDescriptor
{
    public void Add(CustomWebpageJavaScriptFunction obj)
    {
        this.List.Add(obj);
    }

    public void Remove(CustomWebpageJavaScriptFunction obj)
    {
        this.List.Remove(obj);
    }

    public CustomWebpageJavaScriptFunction this[int index]
    {
        get
        {
            return (CustomWebpageJavaScriptFunction)this.List[index];
        }
    }

    public String GetClassName()
    {
        return TypeDescriptor.GetClassName(this, true);
    }

    public AttributeCollection GetAttributes()
    {
        return TypeDescriptor.GetAttributes(this, true);
    }

    public String GetComponentName()
    {
        return TypeDescriptor.GetComponentName(this, true);
    }

    public TypeConverter GetConverter()
    {
        return TypeDescriptor.GetConverter(this, true);
    }

    public EventDescriptor GetDefaultEvent()
    {
        return TypeDescriptor.GetDefaultEvent(this, true);
    }

    public PropertyDescriptor GetDefaultProperty()
    {
        return TypeDescriptor.GetDefaultProperty(this, true);
    }

    public object GetEditor(Type editorBaseType)
    {
        return TypeDescriptor.GetEditor(this, editorBaseType, true);
    }

    public EventDescriptorCollection GetEvents(Attribute[] attributes)
    {
        return TypeDescriptor.GetEvents(this, attributes, true);
    }

    public EventDescriptorCollection GetEvents()
    {
        return TypeDescriptor.GetEvents(this, true);
    }

    public object GetPropertyOwner(PropertyDescriptor pd)
    {
        return this;
    }


    /// <summary>
    /// Called to get the properties of this type. Returns properties with certain
    /// attributes. this restriction is not implemented here.
    /// </summary>
    /// <param name="attributes"></param>
    /// <returns></returns>
    public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        return GetProperties();
    }

    /// <summary>
    /// Called to get the properties of this type.
    /// </summary>
    /// <returns></returns>
    public PropertyDescriptorCollection GetProperties()
    {
        // Create a collection object to hold property descriptors
        PropertyDescriptorCollection pds = new PropertyDescriptorCollection(null);

        // Iterate the list of employees
        for (int i = 0; i < this.List.Count; i++)
        {
            // Create a property descriptor for the employee item and add to the property descriptor collection
            CustomWebpageJavaScriptFunctionCollectionPropertyDescriptor pd = new CustomWebpageJavaScriptFunctionCollectionPropertyDescriptor(this, i);
            pds.Add(pd);
        }
        // return the property descriptor collection
        return pds;
    }
}

对上述集合执行 LINQ 查询的最佳方式是什么?

例如,如何对 CollectionBase 列表的内容执行 .Where() 操作?

【问题讨论】:

  • LINQ 需要泛型枚举,CollectionBase 是非泛型的。尝试先执行OfType&lt;object&gt;(),然后您可以在IEnumerable&lt;object&gt; 实例上使用LINQ。
  • @odyss-jii:非常感谢。这正是我所需要的。如果您发布答案,我会接受答案。

标签: c# linq collectionbase


【解决方案1】:

LINQ 需要泛型枚举,CollectionBase 是非泛型的。尝试先执行OfType&lt;object&gt;(),然后您可以在IEnumerable&lt;object&gt; 实例上使用LINQ。

编辑:如 cmets 中所述,您也可以使用 Cast&lt;object&gt;()。这两种方法的区别在于OfType 将在枚举中包含可以转换为指定类型的元素并跳过其余元素,而Cast 要求所有元素都可以转换为该类型(否则抛出异常)。 Cast 更快,因为它会跳过检查并立即进行施法。

Cast迭代器源码:

foreach (object obj in source) yield return (TResult)obj;

OfType迭代器来源:

foreach (object obj in source) {
    if (obj is TResult) yield return (TResult)obj;
}

【讨论】:

  • @w.b:是的,如果转换为object,Cast 会更快,并且列表不包含空元素,无需额外检查。
  • 再想一想,null 可以“强制转换”为引用类型。
猜你喜欢
  • 1970-01-01
  • 2012-12-25
  • 2012-12-21
  • 1970-01-01
  • 2014-04-25
相关资源
最近更新 更多