【问题标题】:Can I create ternary operators in C#?我可以在 C# 中创建三元运算符吗?
【发布时间】:2011-01-13 10:13:36
【问题描述】:

我想为 a c 等等......我是我自己的短格式的粉丝,自从我在高中学习编程以来,我就一直想创建它。

怎么做?

【问题讨论】:

  • 这是评论吗:-)

标签: c# ternary-operator


【解决方案1】:

不要相信仇恨者;)

可以在 C# 中执行此操作。这是一个示例实现 - 我基于 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);
    }
}

【讨论】:

  • 赞成。但是请记住,例如&lt; 的优先级高于== 的优先级。所以a.Chain() == b &lt; c 不会与(a.Chain() == b) &lt; c 相同(用于检查a 是否等于b 小于c)。
【解决方案2】:

抱歉,您不能在 C# 中创建自己的运算符。

您可以使用扩展方法来启用流畅的语法,例如

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

或者,如果你非常聪明,你可以这样做:

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

这样做很棘手,但有可能。 (提示:定义一个 IsLessThan 返回的自定义对象,该对象跟踪其边界并了解它如何与对象的其他实例组合。本质上,这就是 LINQ-to-SQL 在组合 Where、Select 等方面的工作方式。)

但是您不能在 C# 中定义自己的运算符语法。

如果您对可以定义自己的运算符的语言感兴趣,可以考虑研究 F#。

【讨论】:

    【解决方案3】:

    如果您想对原始数据类型执行此操作,那么您就不走运了。 C# 不支持向它们添加运算符。

    在您自己的数据类型中,可以返回存储中间结果和比较结果的特殊数据类型。不过,我建议您还是坚持使用 c# 语言 - 如果您真的想要 a &lt; b &lt; c 运算符样式,请切换到 Python。

    【讨论】:

    • 将 Python 方法作为双语言程序集成到 C# 函数调用中是否容易? (我使用 Python 的经验一直在帮助朋友调试,它看起来更像是一种脚本语言)
    • Python 是一种成熟的编程语言,IronPython 是它的一种实现,可在 .NET 平台上运行,因此可与 C# 互操作。见ironpython.net
    • 可互操作 - 是的,但它们仍然不能混合;你总是只使用一种语言,所以在 c# 中使用 a
    【解决方案4】:

    没有。不在 C# 中。这种方式的语言扩展在任何当前版本的 C# 中都不可用,但 Luca Bolognese 指出将编译器用作服务和一些可以允许以这种方式扩展语言的功能:http://microsoftpdc.com/Sessions/FT11

    【讨论】:

      【解决方案5】:

      你不能那样做。您只能实现现有的运算符,并且没有三元 .<. c>

      此外,这样的运算符与现有的比较运算符会产生歧义。例如,表达式a == b == c == d 是指((a == b) == c) == d 还是(a == b == c) == d

      【讨论】:

      • 正如我在示例中所展示的,它将基于一个简单的 && 方案来拆分变量,因此 a == b && b == c && c == d。
      • @Scott:你没有抓住重点。编译器如何知道何时将表达式解释为三元比较运算符以及何时使用常规比较运算符? (此外,由于它是三元运算符而不是四元 (?) 运算符,因此它宁愿是 (a == b && b == c) == d。)
      • 嗯,这个想法可能很广泛,类似于带有任意数量参数的函数调用。但它也将基于我用来绕过标准等效测试的库。
      【解决方案6】:

      您是否尝试过在 google 中搜索三元运算符以查看是否已经存在?

      【讨论】:

      • 是的,2 小时(这次)的搜索仍然向我显示 ? b : c 似乎是唯一的三元运算。
      猜你喜欢
      • 2016-08-22
      • 2023-02-16
      • 2019-01-06
      • 2010-12-18
      • 2012-01-15
      • 2020-05-09
      • 2020-10-11
      相关资源
      最近更新 更多