2010-02-05 5 views
6

Voglio creare un operatore ternario per un < b < c che è un < b & & b < c. o qualsiasi altra opzione si può pensare che un < b> c e così via ... Sono un fan delle mie shortform e ho voluto crearlo da quando ho imparato a programmare al liceo.Posso creare operatori ternari in C#?

Come?

+0

Si tratta di una domanda? – Yuliy

+3

Come? - Sì, è – oneat

+0

è questo un commento :-) – Jim

risposta

0

Hai provato a cercare operatori ternari in google per vedere se qualcosa esiste già?

+0

Sì, la ricerca di 2 ore (questa volta) continua a mostrarmi che a? b: c sembra essere l'unica operazione ternaria. –

3

Non puoi farlo. È possibile implementare solo operatori esistenti e non vi è alcun ternario. <. <. operatore in C#.

Inoltre, tale operatore sarebbe ambiguo con gli operatori di confronto esistenti. Ad esempio, l'espressione a == b == c == d significa ((a == b) == c) == d o (a == b == c) == d?

+0

Come ho mostrato nell'esempio, sarebbe basato su un semplice schema && per dividere le variabili in modo che fosse un == b && b == c && c == d. –

+1

@Scott: manca il punto. Come fa il compilatore a sapere quando interpretare un'espressione come operatore di confronto ternario e quando utilizzare operatori di confronto regolari? (Inoltre, poiché è un operatore ternario e non un operatore quadratico (?), Sarebbe piuttosto (a == b && b == c) == d.) – Guffa

+0

Bene, l'idea potrebbe essere espansiva, simile a una funzione chiamare con un numero arbitrario di parametri. Ma sarebbe anche basato su una libreria che userei per aggirare i test di equivalenza standard. –

0

No. Non in C#. L'estensione della lingua in questo modo non è disponibile in nessuna versione corrente di C#, ma Luca Bolognese ha sottolineato l'utilizzo del compilatore come servizio e alcune funzionalità che potrebbero consentire di estendere la lingua in questo modo: http://microsoftpdc.com/Sessions/FT11.

0

Se si vuole fare questo per i tipi di dati primitivi, sei sfortunato. C# non supporta l'aggiunta di operatori a questi.

Nei propri tipi di dati è possibile restituire un tipo di dati speciale che memorizza il risultato intermedio e il risultato di confronto. Tuttavia, ti suggerisco di attenersi al linguaggio C# - se vuoi davvero lo stile operatore a < b < c, passa a Python.

+0

Sarebbe facile integrare i metodi Python in chiamate Funtion in C# come un programma in doppia lingua? (la mia esperienza con Python ha aiutato gli amici a fare il debug e sembrava più un linguaggio di scripting) –

+0

Python è un linguaggio di programmazione pieno zeppo, e IronPython ne è un'implementazione che gira sulla piattaforma .NET e quindi è interoperabile con C#. Vedi http://ironpython.net/ –

+0

Interoperabile - sì, ma ancora non possono essere mescolati; lavori sempre in una sola lingua, quindi usare l'espressione Ondergetekende

4

Siamo spiacenti, non è possibile creare i propri operatori in C#.

Si potrebbe utilizzare metodi di estensione per consentire una sintassi fluente come

bool f = b.IsBetween(a, c); 

Oppure, se si dovesse essere estremamente intelligente, si potrebbe fare:

bool f = a.IsLessThan(b).IsLessThan(c); 

così facendo è difficile, ma possibile. (Suggerimento: definire un oggetto personalizzato restituito da IsLessThan che ne tiene traccia dei limiti e comprende come è combinato con altre istanze dell'oggetto. Essenzialmente, questo è il modo in cui LINQ-to-SQL funziona per combinare Dove, Seleziona e così via.)

Ma non è possibile definire le proprie sintassi dell'operatore in C#.

Se sei interessato alle lingue in cui puoi definire i tuoi operatori, potresti considerare di esaminare F #.

10

Non credete alle nemici;)

È possibile farlo in C#. Ecco un esempio di implementazione — Ho basato il concatenamento sul modo in cui lo fa Icon ... se un confronto ha esito positivo, il risultato è quello del parametro giusto, altrimenti viene restituito un risultato "non riuscito" speciale.

L'unica sintassi aggiuntiva che è necessario utilizzare è la chiamata a Chain() dopo il primo elemento.

class Program 
{ 
    static void Main(string[] args) 
    { 
     if (2.Chain() < 3 < 4) 
     { 
      Console.WriteLine("Yay!"); 
     } 
    } 
} 

public class Chainable<T> where T : IComparable<T> 
{ 
    public Chainable(T value) 
    { 
     Value = value; 
     Failed = false; 
    } 

    public Chainable() 
    { 
     Failed = true; 
    } 

    public readonly T Value; 
    public readonly bool Failed; 

    public static Chainable<T> Fail { get { return new Chainable<T>(); } } 

    public static Chainable<T> operator <(Chainable<T> me, T other) 
    { 
     if (me.Failed) 
      return Fail; 

     return me.Value.CompareTo(other) == -1 
        ? new Chainable<T>(other) 
        : Fail; 
    } 

    public static Chainable<T> operator >(Chainable<T> me, T other) 
    { 
     if (me.Failed) 
      return Fail; 

     return me.Value.CompareTo(other) == 1 
        ? new Chainable<T>(other) 
        : Fail; 
    } 

    public static Chainable<T> operator ==(Chainable<T> me, T other) 
    { 
     if (me.Failed) 
      return Fail; 

     return me.Value.CompareTo(other) == 0 
        ? new Chainable<T>(other) 
        : Fail; 
    } 

    public static Chainable<T> operator !=(Chainable<T> me, T other) 
    { 
     if (me.Failed) 
      return Fail; 

     return me.Value.CompareTo(other) != 0 
        ? new Chainable<T>(other) 
        : Fail; 
    } 

    public static bool operator true(Chainable<T> me) 
    { 
     return !me.Failed; 
    } 

    public static bool operator false(Chainable<T> me) 
    { 
     return me.Failed; 
    } 

    public override bool Equals(object obj) 
    { 
     return Value.Equals(obj); 
    } 

    public override int GetHashCode() 
    { 
     return Value.GetHashCode(); 
    } 
} 

public static class ChainExt 
{ 
    public static Chainable<T> Chain<T>(this T value) where T : IComparable<T> 
    { 
     return new Chainable<T>(value); 
    } 
} 
+1

È davvero fantastico. Quindi puoi fare 'if (1.Chain()

+0

Venerato. Ma ricorda che la precedenza di '<' è superiore a quella di '==', per esempio. Quindi 'a.Chain() == b

+0

nice - out the box soluzione, lo adoro ... – Jim