2013-10-13 12 views
58

Betrachten Sie diesen Code:Warum erlaubt die Methode Remove() einen Char als Parameter?

var x = "tesx".Remove('x'); 

Wenn ich diesen Code ausführen, ich diese Ausnahme erhalten:

start als die Länge der Zeichenfolge kleiner sein muss.

Warum kann ich an diese Methode ein Zeichen anstelle eines int übergeben? Warum erhalte ich keinen Kompilierungsfehler?

enter image description here

Warum hat der Compiler dieses Verhalten?

+1

Syntax: 'entfernen (int start, int length)' –

+3

Vielleicht erwartet die Menschen dies ein Duplikat zu sein, wie ich es tat, aber ich kann nicht finden, überraschend. Man würde denken, dass das vorher gefragt wurde. – 11684

Antwort

92

Sie versuche, 'x' zu entfernen, das ein deklariertes Zeichen ist, x ist gleich 120

Die .Remove benötigt nur 2 Parameter vom Typ int den Start und (optional) zählen zu rem ove von der Schnur.

Wenn Sie ein Zeichen übergeben, wird in die Ganzzahl-Darstellung konvertiert. Das bedeutet, wenn Sie 'x' -> 120 übergeben ist größer als die .Length der Zeichenfolge und deshalb wird es diesen Fehler werfen!

+55

Um dies zu verdeutlichen, ist dies eine Design-Entscheidung, die in der C# -Sprache getroffen wurde, die es als "char" implizit in "int" (ein Rest von C) umwandelbar hält. – Joey

+0

... unterstützt von der Designentscheidung, Zugriffsprüfungen im Rahmen der Überladungsauflösung durchzuführen. Dies macht es sinnlos, eine private '.Remove (Char)' zu definieren. – MSalters

10

Entfernen eines int-Parameter für den Index im String findet msdn zu starten nimmt Zeichen zu entfernen. Der remove-Aufruf muss das Zeichen automatisch in seinen ASCII-Ganzzahl-Index konvertieren und versuchen, das Zeichen an diesem Index aus der Zeichenfolge zu entfernen. Es versucht nicht, das Zeichen selbst zu entfernen.

Wenn Sie nur wollen, alle Fälle zu entfernen, wobei x in der Zeichenfolge auftritt tun:

"testx".Replace("x",string.Empty); 

Wenn Sie den ersten Index von x in der Zeichenfolge entfernen möchten tun:

var value = "testx1x2"; 
var newValue = value.Remove(value.IndexOf('x'), 1); 
+4

Warum die Downvotes? –

+0

Ursprünglich schlug die Antwort '.Replace ('x', '') vor;' wird nicht kompiliert. Es wurde seitdem korrigiert. –

+0

Nicht mein Downvote, aber Entfernen und Ersetzen ist anders. Ersetzen ersetzt alle Vorkommen, das semantisch macht andere Sache –

3

Da übergeben Sie ein Zeichen in der Funktion und dieser Wert wird zur Laufzeit in int konvertiert, daher erhalten Sie den Laufzeitfehler, da der Wert von char zur Laufzeit mehr als die Länge der Zeichenfolge ist dies: -

var x = "tesx"; 
var s = x.Remove(x.IndexOf('x'), 1); 

oder

var s = x.Replace("x",string.Empty); 

.Remove nimmt den int als Parameter. Entfernen benötigt zwei Parameter. Der erste ist die Position in der Zeichenfolge, an der Sie beginnen möchten. (Die Zählung beginnt bei Null.) Der zweite Parameter gibt an, wie viele Zeichen Sie löschen möchten, beginnend mit der von Ihnen angegebenen Position.

Auf einer seitlichen Anmerkung:

Von MSDN:

Diese Methode (.Remove) nicht den Wert der aktuellen Instanz nicht verändert. Stattdessen gibt es einen neuen String, in dem die Anzahl der Zeichen durch die Zähl-Parameter entfernt wurde angegeben. Die Zeichen sind entfernt an der von startIndex angegebenen Position.

+0

Entfernen und Ersetzen ist anders.Ersetzen ersetzt alle Vorkommen, das macht semantisch anderes Ding –

+0

@SriramSakthivel: - ja das ist richtig. Meine Antwort wurde auch mit der Funktion Entfernen aktualisiert. Vielen Dank! –

22

Es gibt keine Überlastung von Remove, die eine char nimmt, so dass die Zeichen implizit auf ein int umgewandelt wird und die Remove Methode versucht sie als ein Index in die Zeichenfolge zu verwenden, die Art und Weise außerhalb der Zeichenfolge ist. Deshalb erhalten Sie diesen Laufzeitfehler anstelle eines Kompilierzeitfehlers, der besagt, dass der Parametertyp falsch ist.

Um Remove zu verwenden, um einen Teil einer Zeichenfolge zu entfernen, müssen Sie zuerst suchen, wo in der Zeichenfolge dieser Teil ist. Beispiel:

var x = "tesx"; 
var x = x.Remove(x.IndexOf('x'), 1); 

Dies wird das erste Vorkommen von 'x' in der Zeichenfolge entfernen. Wenn es mehr als ein Vorkommen sein könnte, und Sie wollen alle entfernen, mit Replace ist effizienter:

var x = "tesx".Replace("x", String.Empty); 
+0

Warum können wir stattdessen char übergeben? –

+0

@ShahroozJefri ㇱ Natürlich gibt es eine implizite Konvertierung von 'char' nach' int' –

+1

@ShahroozJefri Some: Einige Typen können implizit in andere Typen konvertiert werden, zum Beispiel kann ein 'byte' verwendet werden, wenn ein 'int'-Wert wird gebraucht. Ein "char" ist auch implizit in ein "int" umwandelbar, was in manchen Fällen nützlich ist, aber auch verwirrend sein kann, wie in diesem Fall. – Guffa

-1

F: Warum kann ich ein Zeichen anstelle eines int diese Methode übergeben?

A: Weil es nicht in C# implementiert ist!

F: Warum bekomme ich keinen Kompilierungsfehler?

A: weil Zeichen ‚x‘ werfen implizit äquivalent 120

Verwendung unterhalb der Linie

var s = x.Replace("x",string.Empty); 
28

Implicit conversion können Sie diesen Code kompilieren, da char in int kann in int und keine explizite Umwandlung umgewandelt werden muss . Dies wird auch kompilieren und die Antwort wird 600 (120*5) sein -

 char c = 'x'; 
     int i = c; 
     int j = 5; 
     int answer = i * j; 

Von MSDN, impliziter Konvertierung wird zusammengefasst, wie unten -

Implicit conversion

Wie andere gesagt haben Sie Replace oder Remove mit gültigen Eingaben verwenden könnten .

0

Sie können Erweiterungsmethoden verwenden, um eigene Methoden für bereits vorhandene Klassen zu erstellen. Betrachten Sie folgendes Beispiel:

using System; 
using MyExtensions; 

namespace ConsoleApplication 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      const string str1 = "tesx"; 
      var x = str1.RemoveByChar('x'); 
      Console.WriteLine(x); 
      Console.ReadKey(); 
     } 
    } 
} 

namespace MyExtensions 
{ 
    public static class StringExtensions 
    { 
     public static string RemoveByChar(this String str, char c) 
     { 
      return str.Remove(str.IndexOf(c), 1); 
     } 
    } 
} 
Verwandte Themen