8
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 更好?

我正在使用 .NET 4.0 和 VS2010,如果这有关系的话。

编辑

错误信息:

' Public ReadOnly Property Count As Integer' 没有参数并且它的返回类型不能被索引。

4

4 回答 4

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。

于 2013-09-11T14:09:53.927 回答
5

为此目的使用 AsEnumerable:

Public ReadOnly Property SelectedCount() As Integer
    Get
        Return Me.AsEnumerable.Count(Function(obj) obj.IsSelected)
    End Get
End Property
于 2013-09-11T14:20:52.873 回答
5
  1. 您可以投射MeIEnumerable(Of MyObject)

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

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

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

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

  2. 不知道,真的。

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

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

    在 VB.NET 中Me.Count()Me.Count请参阅 ) 的Count属性List(Of T。在 C#this.Count中将引用属性并this.Count()引用扩展方法(因为括号)。

于 2013-09-11T14:14:23.673 回答
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); }
    }
}
于 2013-09-11T14:13:24.023 回答