2010-02-05 16 views
6

Quiero crear un operador ternario para un < b < c que es un < b & < c. o cualquier otra opción que se te ocurra que es < b> c y así sucesivamente ... Soy fanático de mi propia versión corta y quería crear eso desde que aprendí programación en la escuela secundaria.¿Puedo crear operadores ternarios en C#?

¿Cómo?

+0

¿Esto es una pregunta? – Yuliy

+3

¿Cómo? - Sí, es – oneat

+0

es este un comentario :-) – Jim

Respuesta

0

¿Ha intentado buscar operadores ternarios en google para ver si algo ya existe?

+0

Sí, la búsqueda de 2 horas (esta vez) todavía me mostró que? b: c parece ser la única operación ternaria. –

3

No puede hacer eso. Solo puedes implementar operadores existentes, y no hay ternario. <. <. operador en C#.

Además, dicho operador sería ambiguo con los operadores de comparación existentes. Por ejemplo, ¿la expresión a == b == c == d significa ((a == b) == c) == d o (a == b == c) == d?

+0

Como mostré en el ejemplo, se basaría en un esquema simple && para dividir variables de modo que sería a == b && b == c && c == d. –

+1

@Scott: Te estás perdiendo el punto. ¿Cómo sabría el compilador cuándo interpretar una expresión como operador de comparación ternaria y cuándo usar operadores de comparación regulares? (Además, como es un operador ternario y no un operador de cuadratura (?), Preferiría ser (a == b && b == c) == d.) – Guffa

+0

Bueno, la idea podría ser expansiva, similar a una función llamada con un número arbitrario de parámetros. Pero también se basaría en una biblioteca que utilizaría para eludir las pruebas de equivalencia estándar. –

0

No. No en C#. La extensión de idioma de esta manera no está disponible en ninguna versión actual de C#, pero Luca Bolognese apuntó a usar el compilador como un servicio y algunas funcionalidades que podrían permitir extender el idioma de esta manera: http://microsoftpdc.com/Sessions/FT11.

0

Si desea hacer eso para los tipos de datos primitivos, no tiene suerte. C# no admite agregar operadores a esos.

En sus propios tipos de datos es posible devolver un tipo de datos especial que almacena el resultado intermedio y el resultado de la comparación. Sin embargo, le sugiero que simplemente se adhiera al lenguaje C# - si realmente desea el estilo de operador a < b < c, cambie a Python.

+0

¿Sería fácil integrar métodos de Python en llamadas de funtion C# como un programa de lenguaje dual? (mi experiencia con Python ha ayudado a los amigos a depurar y se parecía más a un lenguaje de scripting) –

+0

Python es un lenguaje de programación totalmente independiente y IronPython es una implementación que se ejecuta en la plataforma .NET y, por lo tanto, es interoperable con C#. Ver http://ironpython.net/ –

+0

Interoperable - sí, pero todavía no se pueden mezclar; siempre trabajas en un solo idioma, por lo que usar la expresión a Ondergetekende

4

Lo sentimos, no puede crear sus propios operadores en C#.

Usted podría utilizar los métodos de extensión para permitir una sintaxis fluida como

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

O, si estaban siendo muy inteligente, se podría hacer:

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

hacerlo es difícil, pero posible. (Sugerencia: defina un objeto personalizado que devuelva IsLessThan que rastree sus límites y comprenda cómo se combina con otras instancias del objeto. Básicamente, así es como funciona LINQ-to-SQL con respecto a la combinación de Where, Select, etc.).

Pero no puede definir sus propias sintaxis de operador en C#.

Si le interesan los idiomas en los que puede definir sus propios operadores, puede considerar buscar F #.

10

No creo que los enemigos;)

Usted puede hacer esto en C#. Aquí hay una implementación de ejemplo — He basado el encadenamiento de la forma en que Icon hace el suyo ... si una comparación tiene éxito, el resultado es el del parámetro correcto, de lo contrario se devuelve un resultado especial "fallido".

La única sintaxis adicional que necesita utilizar es la llamada al Chain() después del primer 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

Eso es genial. Entonces puede hacer 'if (1.Chain()

+0

Upvoted. Pero recuerde que la precedencia de '<' es mayor que la de '==', por ejemplo. Entonces 'a.Chain() == b

+0

nice - la solución de la caja, me encanta ... – Jim