Ich möchte eine generische Erweiterungsmethode entwickeln, die die Zeichenfolge in alphabetischer Reihenfolge und dann in aufsteigender Reihenfolge in Längsrichtung anordnet.
ich meine
string[] names = { "Jon", "Marc", "Joel",
"Thomas", "Copsey","Konrad","Andrew","Brian","Bill"};
var query = names.OrderBy(a => a.Length).ThenBy(a => a);
Wie kann die generische Erweiterungsmethode entwickelt werden?
Ich habe es versucht :
public static class ExtensionOperation
{
public static T[] AlphaLengthWise<T>(this T[] names)
{
var query = names.OrderBy(a => a.Length).ThenBy(a => a);
return query;
}
}
Ich erhielt :
Fehler 1: T enthält keine Definition für Länge
Fehler 2: Konvertiert nicht
System.Linq.IOrderedEnumerable
inT[]
.
generic
cool klingt! :)ExtensionOperstion
zuExtensionOperation
Antworten:
Der erste Fehler liegt darin, dass
Length
es sich um eine Eigenschaft derString
Klasse handelt, während in Ihrer generischen Version der Typ des T-Parameters nicht bekannt ist. Es könnte jeder Typ sein.Der zweite Fehler liegt darin, dass Sie nur das Abfrageobjekt zurückgeben, nicht jedoch das tatsächliche Ergebnis. Möglicherweise müssen Sie anrufen,
ToArray()
bevor Sie zurückkehren.Mit kleinen Änderungen könnten Sie sich Folgendes einfallen lassen:
public static class ExtensionOperation { public static IEnumerable<T> AlphaLengthWise<T, L>( this IEnumerable<T> names, Func<T, L> lengthProvider) { return names .OrderBy(a => lengthProvider(a)) .ThenBy(a => a); } }
Was Sie so verwenden könnten:
string[] names = { "Jon", "Marc", "Joel", "Thomas", "Copsey", "Konrad", "Andrew", "Brian", "Bill" }; var result = names.AlphaLengthWise(a => a.Length);
quelle
lengthProvider
mit generischem Code zu verwenden. Es ist nur ein Grund mehr, warum ich Lambdas so sehr liebe. : DWarum möchten Sie dies generisch tun? Benutz einfach
public static class ExtensionOperations { public static IEnumerable<string> AlphaLengthWise(this string[] names) { var query = names.OrderBy(a => a.Length).ThenBy(a => a); return query; } }
quelle
string[]
und nichtIEnumerable<String>
? Sie können das entfernen.ToArray()
und aufgeschoben lassen (wenn ich mich nicht irre).Ich denke, Sie sind vielleicht ein wenig verwirrt über den Zweck von Generika.
Generika sind eine Möglichkeit, eine Klasse oder Methode an einen bestimmten Typ anzupassen. Eine generische Methode oder Klasse kann für jeden Typ verwendet werden. Dies lässt sich am einfachsten in der
List<T>
Klasse veranschaulichen, in der eine Liste eines beliebigen Typs erstellt werden kann. Dies gibt Ihnen die Typensicherheit, wenn Sie wissen, dass die Liste nur diesen bestimmten Typ enthält.Ihr Problem ist darauf ausgelegt, an einem bestimmten Typ, dem
string
Typ, zu arbeiten. Generika werden ein Problem, das einen bestimmten Typ betrifft, nicht lösen.Was Sie wollen, ist eine einfache (nicht generische) Erweiterungsmethode:
public static class ExtensionOperations { public static IEnumerable<string> AlphaLengthWise( this IEnumerable<string> names) { if(names == null) throw new ArgumentNullException("names"); return names.OrderBy(a => a.Length).ThenBy(a => a); } }
Wenn Sie das Argument und den Rückgabetyp festlegen,
IEnumerable<string>
wird dies zu einer nicht generischen Erweiterungsmethode, die für jeden implementierten Typ gelten kannIEnumerable<string>
. Dazu gehörtstring[]
,List<string>
,ICollection<string>
,IQueryable<string>
und viele mehr.quelle
public static class ExtensionOperation { public static IEnumerable<String> AplhaLengthWise( this IEnumerable<String> names) { return names.OrderBy(a => a.Length).ThenBy(a => a); } }
quelle
Kopieren Sie, wie Microsoft es macht:
public static class ExtensionOperation { // Handles anything queryable. public static IOrderedQueryable<string> AlphaLengthWise(this IQueryable<string> names) { return names.OrderBy(a => a.Length).ThenBy(a => a); } // Fallback method for non-queryable collections. public static IOrderedEnumerable<string> AlphaLengthWise(this IEnumerable<string> names) { return names.OrderBy(a => a.Length).ThenBy(a => a); } }
quelle
Sie möchten
IEnumerable<T>
anstelle von verwendenT[]
. Abgesehen davon, werden Sie nicht in der Lage sein zu verwenden ,Length
derT
, da nicht alle Typen eine hatLength
Eigenschaft. Sie können Ihre Erweiterungsmethode auf ändern.OrderBy(a => a.ToString().Length)
Wenn Sie wissen, dass Sie immer mit Zeichenfolgen zu tun haben, verwenden Sie
IEnumerable<String>
anstattIEnumerable<T>
, und Sie könnenLength
sofort auf die Eigenschaft zugreifen .quelle
IOrderedEnumerable<T>
implementiertIEnumerable<T>
, so dass dieser Teil des Problems lösen würde. Wie für dieLength
Eigenschaft, war mein Vorschlag , dassToString()
verwendet wurde , um eine Zeichenfolge zu gewährleisten, oder, wenn er neu er immer mit Streichern tun würde, ÄnderungenT
zustring
.