2011-01-14 9 views
4

ich des Schreibens müde bin x > min && x < max so wawnt ich eine einfache Funktion zu schreiben, aber ich bin nicht sicher, ob ich es richtig mache ... Ich bin eigentlich nicht Cuz Ich erhalte eine Fehlermeldung:Generisches InBetween Funktion

bool inBetween<T>(T x, T min, T max) where T:IComparable 
    { 
     return (x > min && x < max); 
    } 

Fehler:

Operator '>' cannot be applied to operands of type 'T' and 'T' 
Operator '<' cannot be applied to operands of type 'T' and 'T' 

kann ich habe ein schlechtes Verständnis der where Teil in der Funktion

Note erklärt: für diejenigen, die mir sagen werden, dass ich wri sein ting mehr Code als zuvor ... denken an Lesbarkeit =) jede Hilfe

geschätzt wird

EDIT

gelöscht Cuz es aufgelöst wurde =)

ANOTHER EDIT

so nach einigen Kopfschmerzen kam ich mit diesem (uhmm) Ding nach @Jay Idee der extremen Lesbarkeit heraus:

public static class test 
{ 
    public static comparision Between<T>(this T a,T b) where T : IComparable 
    { 
     var ttt = new comparision(); 
     ttt.init(a); 
     ttt.result = a.CompareTo(b) > 0; 
     return ttt; 
    } 

    public static bool And<T>(this comparision state, T c) where T : IComparable 
    { 
     return state.a.CompareTo(c) < 0 && state.result; 
    } 

    public class comparision 
    { 
     public IComparable a; 
     public bool result;   
     public void init<T>(T ia) where T : IComparable 
     { 
      a = ia; 
     } 

    } 
} 

jetzt kann man alles mit extremer Lesbarkeit =)

was denken Sie .. Ich bin kein Guru Leistung vergleichen, so dass alle Verbesserungen sind willkommen

+1

Zu Ihrer EDIT: Erweiterung Methoden müssen statisch sein und in eine statische Klasse. –

+0

oh !!!! Ja, das ist richtig ... mein schlechtes =) – Luiscencio

Antwort

5

IComparable bedeutet, dass das Objekt eine CompareTo-Methode implementiert. Verwenden

public static bool InBetween<T>(this T x, T min, T max) where T:IComparable<T> 
{ 
    return x.CompareTo(min) > 0 && x.CompareTo(max) < 0; 
} 
+0

@Sparkie können Sie mich auf eine Ressource zeigen, um Ihre Änderung zu verstehen? –

+0

Wenn Sie das nicht-generische 'IComparable' verwenden, hat es eine' .CompareTo() 'Methode, die ein' Objekt' erwartet. Also wenn min oder max darauf angewendet werden, müssen sie Objekte sein. (Sie können zum Beispiel Strukturen sein, die keine Objekte sind, sie sind Werttypen). Wenn sie Strukturen sind, sind sie **, was im Grunde ein Objekt zum Verweis auf die Struktur erzeugt, aber das kann in manchen Situationen mehr als 10% mehr kosten, was zu langsameren Code führt (besonders bemerkbar bei Sammlungen). –

+1

Im Fall des generischen 'IComparable ' erwartet die 'CompareTo()' Methode ein T, auf das min und max bereits beschränkt sind. In diesem Fall ist kein Boxen erforderlich. –

3

Sie benötigen die .CompareTo Methode Ihrer Variable zu verwenden und überprüfen < und> 0. (Deshalb haben Sie T auf IComparable beschränkt).

return (x.CompareTo(min) > 0 && x.CompareTo(max) < 0); 
0

Verwendung IComparable.CompareTo():

a.CompareTo (b)> 0 < => a> b

a.CompareTo (b) = 0 < => a = b

a.CompareTo (b) < < 0 => a b <

public bool InBetween<T>(T x, T min, T max) where T:IComparable 
{ 
    return x.CompareTo(min) * x.CompareTo(max) < 0; 
} 
+1

Kluge Wahl der Multiplikation, auch wenn es nicht die transparenteste Lösung ist. –

+0

Ich wäre auch neugierig auf die Leistung Hit –

+1

Multiplikation ist keine kluge Wahl. Stellen Sie sich jemand anders vor, der etwas wie folgt verwendet: 'bool result = InBetween (5,10,4);', das 'true' zurückgibt. Daher müssen Sie eine Überprüfung hinzufügen, um sicherzustellen, dass "max" größer als "min" ist, wenn nicht, dann "return false", was die Methode komplizierter macht. –

0

Sie können versuchen, eine Einschränkung hinzuzufügen, dass T ein IComparable ist, und dann CompareTo anstelle von < und> verwenden.

Aber das wird wahrscheinlich nicht zulassen, dass Sie alle Werttypen senden, die Sie möchten. In diesem Fall erstellen Sie einfach die Überladungen, die Sie benötigen, ohne Generika.

1
return x.CompareTo(min) > 0 && x.CompareTo(max) < 0; 

Wenn Sie für maximale Lesbarkeit gehen, könnten Sie eine Erweiterungsmethode auf IComparable<T>, verwenden und eine Syntax erstellen wie:

return 5.IsBetween(10).and(20); 

oder

return 5.IsBetween(10.and(20)); 

Hier eine Implementierung ist für das zweite Beispiel:

public interface IRange<T> 
{ 
    bool ContainsInclusive(T value); 
    bool ContainsExclusive(T value); 
} 

public class ComparableRange<T> : IRange<T> where T : IComparable<T> 
{ 
    T min; 
    T max; 

    public ComparableRange(T min, T max) 
    { 
     this.min = min; 
     this.max = max; 
    } 

    public bool ContainsInclusive(T value) 
    { 
     return value.CompareTo(min) >= 0 && value.CompareTo(max) <= 0; 
    } 

    public bool ContainsExclusive(T value) 
    { 
     return value.CompareTo(min) > 0 && value.CompareTo(max) < 0; 
    } 
} 

public static class ComparableExtensions 
{ 
    public static IRange<T> and<T>(this T min, T max) where T : IComparable<T> 
    { 
     return new ComparableRange<T>(min, max); 
    } 

    public static bool IsBetween<T>(this T value, IRange<T> range) where T : IComparable<T> 
    { 
     return range.ContainsExclusive(value); 
    } 
} 
+0

Könnten Sie zeigen, wie Sie diese Erweiterungen implementieren? –

+0

wartet immer noch auf diese goldene Implementierung – Luiscencio

+0

@Yuriy @Luiscencio Ich habe ein Update mit einer Beispielimplementierung hinzugefügt. Dies ist eine Übung. keine Empfehlung. Sie könnten dasselbe mit einem Tupel anstelle eines Bereichs tun, aber Sie würden die tatsächliche Vergleichslogik in die Erweiterungsmethode einfügen. – Jay