Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#-基于参数的不同功能覆盖';类型_C#_Inheritance_Methods_Overloading - Fatal编程技术网

c#-基于参数的不同功能覆盖';类型

c#-基于参数的不同功能覆盖';类型,c#,inheritance,methods,overloading,C#,Inheritance,Methods,Overloading,我正在玩AST,我想实现一个类Visitor,它遍历我的树并返回一个值。 我尝试了这种方式,但我的代码无法编译: abstract class ASTVisitor<T> { public abstract T Visit(SumExpr e); public abstract T Visit(ProductExpr e); public abstract T Visit(ConstantExpr e); public abstract T Visit(SymbolE

我正在玩
AST
,我想实现一个类
Visitor
,它遍历我的树并返回一个值。 我尝试了这种方式,但我的代码无法编译:

abstract class ASTVisitor<T> {
  public abstract T Visit(SumExpr e);
  public abstract T Visit(ProductExpr e);
  public abstract T Visit(ConstantExpr e);
  public abstract T Visit(SymbolExpr e); 
}

class DerivateVisitor : ASTVisitor<ASTExpr> {

  public override ASTExpr Visit(SumExpr e){
    return new SumExpr(
      Visit(e.A),
      Visit(e.B));
  }
  public override ASTExpr Visit(ProductExpr e){
    return new SumExpr(
      new ProductExpr(Visit(e.A), e.B),
      new ProductExpr(Visit(e.B), e.A));
  }
  public override ASTExpr Visit(ConstantExpr e){
    return new ConstantExpr(0);
  }
  public override ASTExpr Visit(SymbolExpr e) {
    return new ConstantExpr(1);
  }
}
SumExpr
ProductExpr
ConstantExpr
SymbolExpr
继承自
ASTExpr
。 为什么这不起作用?我怎样才能得到这种行为

以下是编译错误:

exit status 1
main.cs(56,7): error CS1502: The best overloaded method match for `ASTVisitor<ASTExpr>.Visit(SumExpr)' has some invalid arguments
main.cs(45,21): (Location of the symbol related to previous error)
main.cs(56,13): error CS1503: Argument `#1' cannot convert `ASTExpr' expression to type `SumExpr'
main.cs(57,7): error CS1502: The best overloaded method match for `ASTVisitor<ASTExpr>.Visit(SumExpr)' has some invalid arguments
main.cs(45,21): (Location of the symbol related to previous error)
main.cs(57,15): error CS1503: Argument `#1' cannot convert `ASTExpr' expression to type `SumExpr'
main.cs(61,23): error CS1502: The best overloaded method match for `ASTVisitor<ASTExpr>.Visit(SumExpr)' has some invalid arguments
main.cs(45,21): (Location of the symbol related to previous error)
main.cs(61,31): error CS1503: Argument `#1' cannot convert `ASTExpr' expression to type `SumExpr'
main.cs(62,23): error CS1502: The best overloaded method match for `ASTVisitor<ASTExpr>.Visit(SumExpr)' has some invalid arguments
main.cs(45,21): (Location of the symbol related to previous error)
main.cs(62,31): error CS1503: Argument `#1' cannot convert `ASTExpr' expression to type `SumExpr'
Compilation failed: 8 error(s), 0 warnings
退出状态1 main.cs(56,7):错误CS1502:ASTVisitor.Visit(SumExpr)的最佳重载方法匹配具有一些无效参数 main.cs(45,21):(与先前错误相关的符号位置) cs(56,13):错误CS1503:参数`#1'无法将`ASTExpr'表达式转换为`SumExpr'类型 main.cs(57,7):错误CS1502:'ASTVisitor.Visit(SumExpr)'的最佳重载方法匹配具有一些无效参数 main.cs(45,21):(与先前错误相关的符号位置) cs(57,15):错误CS1503:参数`#1'无法将`ASTExpr'表达式转换为`SumExpr'类型 main.cs(61,23):错误CS1502:ASTVisitor.Visit(SumExpr)的最佳重载方法匹配具有一些无效参数 main.cs(45,21):(与先前错误相关的符号位置) cs(61,31):错误CS1503:参数`#1'无法将`ASTExpr'表达式转换为`SumExpr'类型 main.cs(62,23):错误CS1502:ASTVisitor.Visit(SumExpr)的最佳重载方法匹配具有一些无效参数 main.cs(45,21):(与先前错误相关的符号位置) cs(62,31):错误CS1503:参数`#1'无法将`ASTExpr'表达式转换为`SumExpr'类型 编译失败:8个错误,0个警告
提前感谢。

在代码的这一部分中,您正在调用
ASTVisitor。请使用无效参数(e.A)访问它预期的位置(e)

Visit
方法需要以下对象之一(
SumExpr、ProductExpr、ConstantExpr、SymbolExpr
) 您正在通过
e.A
,即
ASTExpr

public override ASTExpr Visit(SumExpr e){
    return new SumExpr(
      Visit(e.A),     // You are passing ASTExpr where as SumExpr is expected
      Visit(e.B));    // You are passing ASTExpr where as SumExpr is expected
  }
这肯定会改变你的逻辑,你将不得不努力

希望这有帮助

问题是

class SumExpr : ASTExpr
{
    public ASTExpr A, B;
    public SumExpr(ASTExpr a, ASTExpr b) =>
      (A, B) = (a, b);

    public override string ToString() => $"({A.ToString()}) + ({B.ToString()})";
}

e、 A是ASTExpr,但没有可以为ASTExpr调用的方法访问

对象类型是在编译期间而不是在运行时定义的

添加以下方法

public override ASTExpr Visit(ASTExpr e)
    {
        if (e as SumExpr != null)
            return Visit(e as SumExpr);

        if (e as ProductExpr != null)
            return Visit(e as ProductExpr);

        if (e as ConstantExpr != null)
            return Visit(e as ConstantExpr);

        if (e as SymbolExpr != null)
            return Visit(e as SymbolExpr);

        throw new ArgumentException();
    }

我建议对@Sergey Prosin的回答稍加改进。使用
作为
可以工作,但速度较慢,因为每次使用都会首先检查类型是否匹配。相反,您可以将
作为
表达式结果分配给变量,然后使用它,或者使用新的
is
模式匹配语法:

public override ASTExpr Visit(ASTExpr e)
{
    if (e is SumExpr sum)
        return Visit(sum);

    if (e is ProductExpr product)
        return Visit(product);

    if (e is ConstantExpr constant)
        return Visit(constant);

    if (e is SymbolExpr symbol)
        return Visit(symbol);

    throw new ArgumentException();
}
更冷
开关
模式匹配:

public override ASTExpr Visit(ASTExpr e)
{
    switch (e)
    {
        case SumExpr sum:
           return Visit(sum); 
        case ProductExpr product:
           return Visit(product);
        case ConstantExpr constant:
           return Visit(constant);
        case SymbolExpr symbol:
           return Visit(symbol);
        default:
           throw new ArgumentException();
    }
}

你能提供更多细节吗?您遇到了什么类型的编译错误我添加了错误请在尝试编译代码时在Visual Studio中包含错误列表中的消息。请提供ASTExpr和SUMEPR定义。它们是如何连接的?是否还需要实现SUMEPR、ProductExpr、ConstantExpr、SymbolExpr和ASTExpr类?但是如果我为
ASTExpr
添加覆盖,所有访问调用都将引用该覆盖。完全正确?不,编译器应该找到最合适的方法。您可以通过单击VSF中的GotoDefinition上下文菜单项进行检查,您可以将其作为visitor实现的示例,并从中获取实现详细信息。提供的代码看起来更简单,因此使用不同名称的Visit方法对meI来说更透明,因为meI只是对参数进行了更改。将更新我的代码:)
public override ASTExpr Visit(ASTExpr e)
{
    if (e is SumExpr sum)
        return Visit(sum);

    if (e is ProductExpr product)
        return Visit(product);

    if (e is ConstantExpr constant)
        return Visit(constant);

    if (e is SymbolExpr symbol)
        return Visit(symbol);

    throw new ArgumentException();
}
public override ASTExpr Visit(ASTExpr e)
{
    switch (e)
    {
        case SumExpr sum:
           return Visit(sum); 
        case ProductExpr product:
           return Visit(product);
        case ConstantExpr constant:
           return Visit(constant);
        case SymbolExpr symbol:
           return Visit(symbol);
        default:
           throw new ArgumentException();
    }
}