c# - Mono C# 编译器将完全有效的表达式解释为错误的类型参数

标签 c# syntax compiler-errors

当我意识到可能无法区分使用 < 的表达式时,我正在努力创建自己的静态类型语言。运算符和类或方法的类型参数。

这样做的主要原因是,像 C# 一样,类在使用之前不必全部进行前向声明,因此当标识符在 < 之后被解析时。 ,它可以是像 valueA < valueB 这样的表达式或者它可能是一个类型参数,如 valueA<valueB> .

所以我想,也许如果有一个结束 > ,然后它可以被解析为一个类型参数,但后来我想起我希望我的语言有运算符重载,所以像 valueA < valueB > (valueC) 这样的表达式可能是完全有效的。

我决定尝试其他语言,我发现 C# 与我试图创建的语言最相似,我可能已经破坏了它。

表达式 foo < bar > (2)在下面的代码中应该是一个完全有效的表达式,因为类重载 <>运营商。

据我所知,表达式应该被解析为 (foo < bar) > (2) ,但我收到一个错误,指出 "The variable 'foo' cannot be used with type arguments."为了证明这个表达式应该是有效的,我翻转了 <>标志使表情看起来像 foo > bar < (2) ,并且该程序的编译和打印出的内容完全符合您的预期,MainClass+baz .

在这个特定的例子中,编译器可能会解决这个问题,因为它知道 foo是一个变量,它可以假设 <表示一个表达式,但如果 foo 是另一个类的静态成员,则无法区分 <表达式和类型参数。

using System;

class MainClass {
  public static void Main (string[] args) {

    baz foo = new baz();

    baz bar = new baz();

    // perfectly valid expression, results in error: The variable `foo' cannot be used with type arguments
    Console.WriteLine(foo < bar > (2));

  }

  class baz {
    public static baz operator<(baz l, baz r) {
      return l;
    }

    public static baz operator>(baz l, baz r) {
      return l;
    }

    public static baz operator<(baz l, int r) {
      return l;
    }

    public static baz operator>(baz l, int r) {
      return l;
    }

  }

  public String toString() {
    return "baz";
  }

}

我的问题是,应该如何在 C# 编译器和其他语言中处理这个问题?

我看到几个选项:
  • 不明确的情况报错
  • 也许还有更多的上下文可以用来解决这种歧义
  • C# 本质上已经被破坏了,我们应该在 future 的语言中为类型参数开发一种新的语法。如果是这样,它应该是什么样子?

  • 也许对此有某种标准,但我认为接受这只是疏忽,我们至少应该选择选项 1。

    最佳答案

    foo是局部变量,但您尝试将其用作类类型名称...

    因此,它根本不是一个完全有效的表达式。

    你不能写:

    baz foo = new baz();
    baz bar = new baz();
    
    Console.WriteLine(foo<bar>(2));
    

    但是你可以写:
    var instance = baz<int>(2);
    

    如果你有:
    class baz<T>
    {
    }
    

    在这里,您尝试使用泛型类型参数 int 创建类 baz 的实例,而不使用 new关键字或者它可能是一个误写的强制转换,但编译器不知道。

    当您定义类时 baz<T>这就是所谓的 开放泛型 .

    当你实例化 baz<int>这就是所谓的封闭构造泛型 .

    您编写下面的代码应该是一个完全有效的表达式,因为该类具有重载的 < 和 > 运算符...

    但是编译器无法解释val1 < val2 > (val3)val1 < val2 && val2 > (val3)与数学规则一样,或作为 (val1 < val2) > (val3)就像你写的一样,因为运算符 <>()优先于 <> .

    编译器认为您尝试使用 baz of T ,所以编译器输出错误,因为编译器无法在两种情况之间选择,在<>()之间和 <下一个 > .

    所以编译器将其解释为 Type<Type>(parameter)没有别的。

    关于c# - Mono C# 编译器将完全有效的表达式解释为错误的类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58652280/

    相关文章:

    c++ - gluTessCallback 错误 C2440

    c# - 调用 WCF 服务时如何触发事件(客户端)

    string - 使用VBA选择不相邻的范围

    python - Python中的花括号和方括号有什么区别?

    c - 对 xxx include 的 undefined reference 不起作用

    java - JDBC Netbeans java+mysql项目连接语句显示错误, `Erroneous sym type: java.lang.Object.getConnection`

    c# - 适用于 Windows 上 Mono 的良好 IDE

    c# - 属性中的冒号被 XmlDocument 截断了吗?

    c# - 使用 params 关键字从 PowerShell 调用 C# 函数

    sql - 我有一个大查询,我该如何调试它?