Могу ли я создать троичные операторы в C #? - PullRequest
6 голосов
/ 05 февраля 2010

Я хочу создать троичный оператор для a c и так далее ... Я фанат своей собственной короткой формы, и я хотел создать это, так как я изучал программирование в средней школе.

Как?

Ответы [ 6 ]

10 голосов
/ 13 мая 2010

Не верь ненавистникам;)

Вы можете сделать это в C #. Вот пример реализации & mdash; Я основал цепочку на том, как Icon делает их ... если сравнение успешно, получается результат с правильным параметром, в противном случае возвращается специальный "неудачный" результат.

Единственный дополнительный синтаксис, который вам нужно использовать, - это вызов Chain() после первого элемента.

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);
    }
}
4 голосов
/ 05 февраля 2010

Извините, вы не можете создавать свои собственные операторы в C #.

Вы можете использовать методы расширения, чтобы включить свободный синтаксис, такой как

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

Или, если вы очень умны, вы можете сделать:

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

сделать это сложно, но возможно. (Подсказка: определите пользовательский объект, который возвращает IsLessThan, который отслеживает его границы и понимает, как он комбинируется с другими экземплярами объекта. По сути, именно так работает LINQ-to-SQL в отношении объединения Where, Select и т. Д.)

Но вы не можете определить собственные синтаксисы операторов в C #.

Если вас интересуют языки, где вы можете определить свои собственные операторы, вы можете рассмотреть F #.

3 голосов
/ 05 февраля 2010

Вы не можете этого сделать. Вы можете реализовать только существующие операторы, а троичных нет. <. <. оператор в C #. </p>

Кроме того, такой оператор был бы неоднозначным с существующими операторами сравнения. Например, будет ли выражение a == b == c == d означать ((a == b) == c) == d или (a == b == c) == d?

0 голосов
/ 05 февраля 2010

Если вы хотите сделать это для примитивных типов данных, вам не повезло. C # не поддерживает добавление операторов к ним.

В ваших собственных типах данных можно вернуть специальный тип данных, в котором хранятся промежуточный результат и результат сравнения. Однако я предлагаю вам просто придерживаться языка c # - если вам действительно нужен стиль оператора a < b < c, переключитесь на Python.

0 голосов
/ 05 февраля 2010

Нет. Не в C #. Расширение языка таким способом недоступно ни в одной текущей версии C #, но Лука Болоньезе указал на использование компилятора в качестве службы и некоторых функциональных возможностей, которые могут позволить расширить язык таким образом: http://microsoftpdc.com/Sessions/FT11.

0 голосов
/ 05 февраля 2010

Вы пытались искать троичных операторов в Google, чтобы увидеть, существует ли что-то уже?

...