2010-04-06 18 views
7

G'Day Mates -C# String Überladen von Operatoren

Was ist der richtige Weg (ohne das Argument, ob es ratsam) < die String-Operatoren zu überlasten,>, < = und> =?

Ich habe es fünf Möglichkeiten bis zum Sonntag versucht und ich bekomme verschiedene Fehler - mein bester Schuss erklärte eine partielle Klasse und Überlastung von dort, aber es wird aus irgendeinem Grund nicht funktionieren.

namespace System 
{ 
    public partial class String 
    { 
     public static Boolean operator <(String a, String b) 
     { 
      return a.CompareTo(b) < 0; 
     } 

     public static Boolean operator >(String a, String b) 
     { 
      return a.CompareTo(b) > 0; 
     } 
    } 

}

+0

FYI: Teilklassen müssen sich in derselben Baugruppe (Projekt) befinden. –

+0

Dieser Operator ist bereits für Strings definiert, daher ist es nicht sinnvoll, sie neu zu definieren. Es könnte viel Code kaputt machen, wenn es möglich wäre. – Phil1970

Antwort

16

String ist eine versiegelte Klasse. Sie können nicht davon erben, und ohne die ursprüngliche Quelle für String können Sie keine partielle Klasse davon kompilieren. Selbst wenn Sie die Quelle (über Reflector oder über den Visual Studio-Symbol-Download) erhalten, haben Sie immer noch Probleme, da es sich um einen erstklassigen Bürger in der Laufzeit handelt.

Benötigen Sie wirklich < und> als Operatoren für die Zeichenfolge? Wenn ja ... warum nicht einfach extension methods verwenden?

public static bool IsLessThan(this string a, string b) 
{ 
    return a.CompareTo(b) < 0; 
} 

public static bool IsGreaterThan(this string a, string b) 
{ 
    return a.CompareTo(b) > 0; 
} 


// elsewhere... 
foo.IsLessThan(bar); // equivalent to foo < bar 
+4

Selbst wenn er davon erben könnte, wären nur Instanzen seines geerbten Typs **, auf die als geerbter Typ ** verwiesen wird, in der Lage, die alternativen Operatoren zu verwenden. Da Operatoren nicht polymorph sind (sie sind überladen, nicht überschrieben), würde das Verweisen auf den Subtyp als "String" die alternative Operatorfunktionalität eliminieren. –

+0

@Adam Robinson: genau. Fazit: @ScottSEA kann einfach nicht das machen, was er will. – Randolpho

+1

Ich weiß, dass es in Ihrem Beitrag nicht um Erweiterungsmethoden geht, aber es könnte nützlich sein, einen Link bereitzustellen. Für jemanden, der neu in C# ist, sieht es so aus, als würde es falsch genannt. http://msdn.microsoft.com/en-ca/library/vstudio/bb383977.aspx – jgreep

5

Haben Sie die System.String Klasse bedeuten? Das ist unmöglich in C#. Sie können Erweiterungsoperatoren nicht zu einer vorhandenen Klasse hinzufügen. Es ist jedoch ein sehr nachgefragtes Feature.

10

Die einfache Antwort ist, dass Sie nicht können; Es gibt keine Möglichkeit, die Operatoren für eine andere Klasse zu ändern. Teilklassen sind nur für Klassen zulässig, die sowohl als partial in allen Dateien als auch definiert in der gleichen Baugruppe definiert sind.

3
  • Sie können nicht eine partielle Klasse für String haben, da die Zeichenfolge Klasse selbst nicht Teil ist und daher nicht mit dem Teil-Klasse arbeiten.

  • Die Zeichenfolge ist versiegelt, so dass Sie davon erben und den Operator dann überlasten können.

Kurz gesagt, ach, Sie nicht tun, was mit dir zu tun.

Nicht wissen, was Sie genau machen wollen, kann ich keine gute Alternative vorschlagen. Aber werfen Sie einen Blick auf extension methods, die oft für Situationen gut sind. Abgesehen davon, ob Sie sollten :), könnten Sie der String-Klasse eine Methode namens IsGreaterThan hinzufügen und True oder False zurückgeben, wie Sie möchten. Das ist gut, weil Sie der Erweiterungsmethode einen Namen geben können, der ihre Bedeutung verdeutlicht, die vorhandenen Operatoren im Takt hält (worüber Sie sowieso keine Wahl haben) und schnellen/einfachen Code ermöglicht.

1

Sie können den Operator> = und < = nicht direkt überlasten, aber Sie können das gleiche Ergebnis erzielen, indem Sie das> und das == separat überladen.

Ihr Code scheint mir korrekt, außer der Tatsache, dass Sie die Überladung für == verpassen.

Scheint, ich habe mich geirrt, jedoch können Sie immer wieder auf Reflexion zurückgreifen. Ich denke, wenn Sie etwas graben und hacken, können Sie es mit Reflektion arbeiten lassen, um die Klasse zu erweitern, da Reflektion erlaubt, Funktionen hinzuzufügen oder Funktionskörper zur Laufzeit zu tauschen.

Ob es ratsam und gute Praxis ist, bezweifle ich es. Es gibt einen Grund, warum die Klasse versiegelt ist. Das, was ich erwähnte, kann unter bestimmten Umständen zu undefiniertem Verhalten aufgrund einiger Annahmen führen, die das .net-Framework für Zeichenfolgen vornimmt. Die Wahrscheinlichkeit ist groß, dass die String-Klasse intern kollabiert.

+1

Downvote wegen schlechter Praxis? : p – Henri

15

Es gibt keine Möglichkeit zu ersetzen alle eingebautes Verhalten des Compilers mit Ihren eigenen. Sie können vorhandene integrierte Operatoren für Vergleiche, Konvertierungen, Arithmetik usw. nicht überschreiben. Das ist von Entwurf; Es ist so, dass jemand Ihren Code lesen kann und wissen, dass int x = M(); int y = x + 2; Integer-Arithmetik, im Gegensatz zu etwa Formatierung Ihrer Festplatte.

Können Sie erklären, warum Sie dies tun möchten? Vielleicht gibt es einen besseren Weg, um zu tun, was Sie wollen.

+0

Danke für diese Antwort. Als eine hart umrissene Designentscheidung würde es erklären, warum vor zehn Jahren individuelle String-Operatoren nicht möglich waren und immer noch nicht sind. –

+0

Was würde ich suchen ist eher darzustellen 'String.Concat (Enumerable.Repeat („Hallo“, 4))' als '„Hallo“* 4' Weiß jemand, ob das möglich ist in irgendeiner Weise? –

+1

@AlexeyKhoroshikh: Nein. Es gibt keinen Typ, auf dem Sie diesen Operator definieren könnten. –

Verwandte Themen