为什么List(Of T)没有Count()?

时间:2013-09-11 14:07:00

标签: .net vb.net linq extension-methods

Public Class MyList
    Inherits List(Of MyObject)

    Public ReadOnly Property SelectedCount() As Integer
        Get
            Return Me.Count(Function(obj) obj.IsSelected)
        End Get
    End Property
End Class

上面的代码会导致编译时错误。如您所见,我正在尝试使用扩展方法Count(<predicate>)。我想这个错误是因为List类本身也存在一个类似命名的属性Count,隐藏了扩展成员。

我的问题是:

  1. 我是否需要明确地将我的课程转换为其他内容才能访问Count扩展方法?如果是这样,在上述场景中究竟应该是哪个类?

  2. 为什么编译器不能从使用中推断出我所指的方法而不是属性?

  3. 考虑到这是一种使用频繁的方法(有时可能每秒被调用数百次),是否会导致显着的开销?

  4. 在这方面C#是否优于VB.NET?

  5. 如果有事可做,我正在使用带有VS2010的.NET 4.0。

    修改

    错误讯息:

      

    'Public ReadOnly Property Count As Integer'没有参数及其参数   返回类型无法编入索引。

4 个答案:

答案 0 :(得分:6)

不使用扩展方法语法调用方法:

Public Class MyList
    Inherits List(Of MyObject)

    Public ReadOnly Property SelectedCount() As Integer
        Get
            Return Enumerable.Count(Me, Function(obj) obj.IsSelected)
        End Get
    End Property
End Class

确保已向System.Linq添加导入。

答案 1 :(得分:5)

  1. 您可以将Me投射到IEnumerable(Of MyObject)

    Return DirectCast(Me, IEnumerable(Of MyObject)).Count(Function(obj) obj.IsSelected)
    

    或直接使用Enumerable.Count()方法:

    Return Enumerable.Count(Me, Function(obj) obj.IsSelected)
    

    扩展方法由编译器转换为直接静态(VB中的shared)方法调用,因此没有区别。

  2. 真的不知道。

  3. 转换为基础类型不会更改对象本身,因此不存在性能损失(除非涉及boxing,此处不是这种情况)。

  4. C#不允许带参数的属性,并且需要在没有()的情况下调用属性,所以是的,在这种情况下更好。

    在VB.NET中,Me.Count()Me.Count都引用Count的{​​{1}}属性。在C#List(Of T中引用属性,this.Count引用扩展方法(因为括号)。

答案 2 :(得分:5)

为此目的使用AsEnumerable:

Public ReadOnly Property SelectedCount() As Integer
    Get
        Return Me.AsEnumerable.Count(Function(obj) obj.IsSelected)
    End Get
End Property

答案 3 :(得分:1)

要回答#4,这在C#中运行良好:

public class MyObject { public bool IsSelected { get { return true; } } }

public class MyList : List<MyObject>
{
    public int SelectedCount
    {
        get { return this.Count(x => x.IsSelected); }
    }
}