Wie gebe ich Enumerable.Count () anstelle von List.Count an?

8

Wenn Sie versuchen, Enumerable.Count ()

%Vor%

Der Fehler ist:

  

'Öffentliche ReadOnly-Eigenschaft Count As Integer' hat keine Parameter und seine   Rückgabetyp kann nicht indiziert werden.

Ich bin auf .NET 4.0 ausgerichtet, daher sollten Erweiterungsmethoden unterstützt werden. Es ist auch erwähnenswert, dass der entsprechende Code in C # die Erweiterungsmethode korrekt ermittelt ...

Warum kann der Compiler die Verwendung von Enumerable.Count nicht ableiten, wenn das Prädikat übergeben wird, das ich als Argument übergeben habe, und wie kann ich die Erweiterungsmethode anstelle der Count-Eigenschaft der List verwenden?

    
Dan J 12.04.2013, 00:48
quelle

4 Antworten

1

Um Ihre Frage zu zu beantworten, warum VB nicht kann, was C # in diesem Fall kann ...

Mit

VB können Sie auf Eigenschaften mit () nach dem Namen zugreifen und Funktionen ohne Parameter aufrufen, indem Sie () auslassen. Auch Indexer verwenden abgerundete Klammern anstelle von eckigen Klammern, die Sie in C # haben. Dies sind Beispiele für enorme VB-Funktionen, die entwickelt wurden, um die Programmierung zu vereinfachen, was tatsächlich zu mehrdeutigen, schwer verständlichen und fehleranfälligen Code führt.

In diesem speziellen Fall sieht VB also, dass Sie auf "Count" zugreifen und die Klammern, nachdem es ein Indexer für die Count-Eigenschaft ist, anstelle von Argumenten für die Count-Funktion annehmen.

C # sieht die abgerundeten Klammern und stellt fest, dass Sie nicht auf den Indexer zugreifen, Sie müssen eine Funktion aufrufen, sucht also nach einer Funktion.

Natürlich gibt es auch in C # Raum für Mehrdeutigkeiten. Beispielsweise wird eine Eigenschaft mit demselben Namen wie eine Erweiterungsmethode, die einen Delegattyp zurückgibt, vor der Erweiterungsmethode ...

aufgerufen %Vor%

Ah ... glückliche Tage.

Wie man die Funktion IEnumerable.Count () aufruft, eine Umwandlung (vorzugsweise DirectCast() ) oder die direkte Ausführung der Erweiterungsmethode Enumerable.Count(...) , ist bei weitem vorzuziehen, wenn man ein ganz neues Array zum Aufruf von count on erstellt. .!

    
Mark 11.11.2013, 18:36
quelle
7

Der VB.Net-Compiler versucht zuerst Count in der List -Instanz nachzuschlagen und findet die Count -Eigenschaft. Diese Eigenschaft wird anstelle der Erweiterungsmethode verwendet, da Felder und Eigenschaften Erweiterungsmethoden immer nach Namen schattieren. Ich weiß nicht, wo dies in der Visual Basic-Language-Spezifikation angegeben ist, aber Sie können mehr in diesem MSDN lesen Magazin Artikel :

  

Felder und Eigenschaften überschreiben Erweiterungsmethoden immer nach Namen. Abbildung 4 zeigt eine Erweiterungsmethode und ein öffentliches Feld mit demselben Namen und verschiedenen Anrufen. Obwohl die Erweiterungsmethode ein zweites Argument enthält, überschattet das Feld die Erweiterungsmethode nach Namen und alle Aufrufe, die diesen Namen verwenden, führen zum Zugriff auf das Feld. Die verschiedenen überlasteten Aufrufe werden alle kompiliert, aber ihre Ergebnisse zur Laufzeit können unerwartet sein, da sie an die Eigenschaft binden und das Standardeigenschaftenverhalten verwenden, um ein einzelnes Zeichen zurückzugeben oder zu einer Laufzeitausnahme zu führen. Es ist wichtig, die Namen Ihrer Erweiterungsmethoden zu wählen, um Konflikte mit Eigenschaften, Feldern und vorhandenen Instanzmethoden zu vermeiden.

Also könnte Count(Function(foo) foo.Bar = "a") bedeuten: Rufen Sie die Count -Eigenschaft mit Function(foo) foo.Bar = "a" auf, oder nehmen Sie das Ergebnis der Count -Eigenschaft und indizieren Sie sie mit Function(foo) foo.Bar = "a" , was seit der Indizierung absolut gültig sein könnte Eigenschaften in VB.Net können beliebige Parameter annehmen.

Dies funktioniert in C # (ich denke), weil es für den C # -Compiler einfacher ist, zwischen Methodenaufrufen und einem Eigenschaftszugriff zu unterscheiden, weil C # im Gegensatz zu VB.NET keine willkürlichen Parameter für Eigenschaften und indizierte Eigenschaften zulässt.

Um die Erweiterungsmethode zu verwenden, rufen Sie sie so auf, als würden Sie jede andere statische (geteilte) Methode aufrufen:

%Vor%

oder rufen Sie Call auf IEnumerable explizit auf:

%Vor%     
sloth 04.10.2013 14:59
quelle
2

Ich bin nicht sicher, warum Sie die Überladung nicht als Option erhalten, aber Sie sollten in der Lage sein, die Liste in IEnumerable(Of Foo) zu umwandeln, zu welchem ​​Zeitpunkt der Compiler List(Of Foo).Count property nicht mehr erlaubt.

%Vor%     
Gideon Engelberth 12.04.2013 02:54
quelle
1

Wenn die Liste in ein Array konvertiert wird, funktioniert

%Vor%     
dbasnett 12.04.2013 13:10
quelle

Tags und Links