使用“base”时,基类方法中的代码不执行关键词

发布于 2024-09-26 02:45:27 字数 1876 浏览 1 评论 0 原文

当重写抽象方法并尝试调用我当前正在重写的基类的方法时,我看到一个非常奇怪的问题。

//In Dll "A"
namespace Rhino.Etl.Core.Operations
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    public class Row {}

    public interface IOperation
    {
        IEnumerable<Row> Execute(IEnumerable<Row> rows);
    }

    public abstract class AbstractOperation : IOperation
    {
        public abstract IEnumerable<Row> Execute(IEnumerable<Row> rows);
    }

    public abstract class AbstractDatabaseOperation : AbstractOperation
    {
    }

    public abstract class SqlBulkInsertOperation : AbstractDatabaseOperation
    {
        public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
        {
            Console.WriteLine("SqlBulkInsertOperation");
            return rows;
        }
    }
}

//In console app "B"
namespace MyStuff
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    class Program
    {
        static void Main(string[] args)
        {
            ActualEtlOperation e = new ActualEtlOperation();
            e.Execute(new Row[0]);

            Console.ReadLine();
        }
    }

    public abstract class SqlBulkInsertWithTruncateOperation : SqlBulkInsertOperation
    {
        public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
        {
            Console.WriteLine("Truncate");
            base.Execute(rows);
            return rows;
        }
    }

    public class ActualEtlOperation : SqlBulkInsertWithTruncateOperation
    {

    }
}

基本上,SqlBulkInsertOperation 并没有做我需要它做的事情,所以我需要在通过覆盖它来调用 Execute(rows) 之前和之后做一些工作。但是SqlBulkInsertOperation.Execute(Rows)中的代码没有执行。

在 Visual Studio 的调试器中运行此代码时,调试器不会执行该代码。当我将鼠标悬停在 Visual Studio 编辑器中的“base”上时,它知道基类的类型为 SqlBulkInsertOperation。

我缺少什么?

I'm seeing a very strange problem when overriding an abstract method and trying to call the base class's method that I'm currently overriding.

//In Dll "A"
namespace Rhino.Etl.Core.Operations
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    public class Row {}

    public interface IOperation
    {
        IEnumerable<Row> Execute(IEnumerable<Row> rows);
    }

    public abstract class AbstractOperation : IOperation
    {
        public abstract IEnumerable<Row> Execute(IEnumerable<Row> rows);
    }

    public abstract class AbstractDatabaseOperation : AbstractOperation
    {
    }

    public abstract class SqlBulkInsertOperation : AbstractDatabaseOperation
    {
        public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
        {
            Console.WriteLine("SqlBulkInsertOperation");
            return rows;
        }
    }
}

//In console app "B"
namespace MyStuff
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    class Program
    {
        static void Main(string[] args)
        {
            ActualEtlOperation e = new ActualEtlOperation();
            e.Execute(new Row[0]);

            Console.ReadLine();
        }
    }

    public abstract class SqlBulkInsertWithTruncateOperation : SqlBulkInsertOperation
    {
        public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
        {
            Console.WriteLine("Truncate");
            base.Execute(rows);
            return rows;
        }
    }

    public class ActualEtlOperation : SqlBulkInsertWithTruncateOperation
    {

    }
}

Basically, the SqlBulkInsertOperation does not do what I need it to do, so I need to do a little work before and after I call Execute(rows) on it by overriding it. But the code in SqlBulkInsertOperation.Execute(Rows) is not executed.

When running this code in the debugger in Visual Studio the debugger the code's not executed. When I hover the mouse over "base" in the Visual Studio editor it knows the base class is of type SqlBulkInsertOperation.

What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

吹梦到西洲 2024-10-03 02:45:27

编辑:我发现了问题......讽刺的是,我对 Eric 的“心灵调试”评论并不是那么遥远,因为 这篇博文。这是一个简短但完整的程序,它将演示正在发生的事情...

using System;
using System.Collections.Generic;

public class Row {}

public abstract class BaseDatabaseOperation
{
    public abstract IEnumerable<Row> Execute(IEnumerable<Row> rows);
}

public abstract class SqlBulkInsertOperation : BaseDatabaseOperation
{
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
    {
        Console.WriteLine("In SqlBulkInsertOperation.Execute");
        foreach (var row in rows)
        {
            yield return row;
        }
    }
}

public class MyOverride : SqlBulkInsertOperation
{
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
    {
        Console.WriteLine("In MyOverride.Execute");
        return base.Execute(rows);
    }
}

class Test
{
    static void Main()
    {
        BaseDatabaseOperation x = new MyOverride();
        x.Execute(new Row[0]);
    }
}

它将打印“In MyOverride.Execute”,但它*不会“打印“In SqlBulkInsertOperation.Execute”...因为该方法是使用迭代器块实现的 当然,

您可以更简单地演示这一点:

using System;
using System.Collections.Generic;

class Test
{
    static IEnumerable<string> Foo()
    {
        Console.WriteLine("I won't get printed");
        yield break;
    }

    static void Main()
    {
        Foo();
    }
}

没有任何东西使用该方法的返回值 - 它被传递回 Main,但没有任何东西调用 GetEnumerator() ,然后 MoveNext() 结果......因此该方法的主体永远不会执行

。 com/Articles/Chapter6/IteratorBlockImplementation.aspx" rel="noreferrer">我关于迭代器块的文章,Eric 博客文章的第二部分,或从 《C# 深度深度学习》第一版主页(第 6 章介绍迭代器块,并且免费),了解更多详细信息。

EDIT: I've found the problem... and ironically, my "psychic debugging" comment to Eric wasn't so far off, given this blog post. Here's a short but complete program which will demonstrate what's going on...

using System;
using System.Collections.Generic;

public class Row {}

public abstract class BaseDatabaseOperation
{
    public abstract IEnumerable<Row> Execute(IEnumerable<Row> rows);
}

public abstract class SqlBulkInsertOperation : BaseDatabaseOperation
{
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
    {
        Console.WriteLine("In SqlBulkInsertOperation.Execute");
        foreach (var row in rows)
        {
            yield return row;
        }
    }
}

public class MyOverride : SqlBulkInsertOperation
{
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
    {
        Console.WriteLine("In MyOverride.Execute");
        return base.Execute(rows);
    }
}

class Test
{
    static void Main()
    {
        BaseDatabaseOperation x = new MyOverride();
        x.Execute(new Row[0]);
    }
}

That will print "In MyOverride.Execute" but it *won't" print "In SqlBulkInsertOperation.Execute"... because that method is implemented with an iterator block.

Of course, you can demonstrate this much more simply:

using System;
using System.Collections.Generic;

class Test
{
    static IEnumerable<string> Foo()
    {
        Console.WriteLine("I won't get printed");
        yield break;
    }

    static void Main()
    {
        Foo();
    }
}

Nothing is using the return value of the method - it's being passed back to Main, but nothing ever calls GetEnumerator() on it, and then MoveNext() on the result... so the body of the method is never executed.

See my article on iterator blocks, part two of Eric's blog post, or download chapter 6 from the home page of the first edition of C# in Depth (chapter 6 covers iterator blocks, and is free) for more details on this.

つ低調成傷 2024-10-03 02:45:27

这是我运行的代码:

using System;
using System.Collections.Generic;
public class Row {}
public abstract class BaseDatabaseOperation 
{ 
    public abstract IEnumerable<Row> Execute(IEnumerable<Row> rows); 
} 

public abstract class SqlBulkInsertOperation : BaseDatabaseOperation 
{ 
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows) 
    { 
        Console.WriteLine("base");
        return null;
    } 
} 

public class MyOverride : SqlBulkInsertOperation 
{ 
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows) 
    { 
        Console.WriteLine("override");
        base.Execute(rows);
        return null;
    } 
} 

static class P 
{
    static void Main()
    {
        var m = new MyOverride();
        m.Execute(null);
    }
}

运行良好;它产生“覆盖”和“基础”。

告诉您什么:修改我在此处发布的程序,以便它产生您遇到的问题,我们将对此进行分析。当您无法真正看到有问题的真实代码时,分析问题是非常困难的。

Here's the code I ran:

using System;
using System.Collections.Generic;
public class Row {}
public abstract class BaseDatabaseOperation 
{ 
    public abstract IEnumerable<Row> Execute(IEnumerable<Row> rows); 
} 

public abstract class SqlBulkInsertOperation : BaseDatabaseOperation 
{ 
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows) 
    { 
        Console.WriteLine("base");
        return null;
    } 
} 

public class MyOverride : SqlBulkInsertOperation 
{ 
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows) 
    { 
        Console.WriteLine("override");
        base.Execute(rows);
        return null;
    } 
} 

static class P 
{
    static void Main()
    {
        var m = new MyOverride();
        m.Execute(null);
    }
}

It runs fine; it produces "override" and "base".

Tell you what: modify the program I've posted here so that it produces the problem you are experiencing, and we'll analyze that. It is very difficult to analyze a problem when you cannot actually see the real code that is having problems.

相权↑美人 2024-10-03 02:45:27

对我来说效果很好。您的代码需要进行一些清理 - 您确定正在编译并执行此代码,而不是调试旧版本的代码吗?

class Program
{
    public class Row { }

    public abstract class BaseDatabaseOperation
    {
        public abstract IEnumerable<Row> Execute(IEnumerable<Row> rows);
    }

    public abstract class SqlBulkInsertOperation : BaseDatabaseOperation
    {
        public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
        {
            Console.WriteLine("done");
            return rows;
        }
    }

    public class MyOverride : SqlBulkInsertOperation
    {
        public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
        {
            return base.Execute(rows);
        }
    }

    static void Main(string[] args)
    {
        var x = new MyOverride();
        x.Execute(null);
    }
}

Works fine for me. Your code needs a little cleanup - are you sure you're compiling and executing this code, and not debugging an older build of your code?

class Program
{
    public class Row { }

    public abstract class BaseDatabaseOperation
    {
        public abstract IEnumerable<Row> Execute(IEnumerable<Row> rows);
    }

    public abstract class SqlBulkInsertOperation : BaseDatabaseOperation
    {
        public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
        {
            Console.WriteLine("done");
            return rows;
        }
    }

    public class MyOverride : SqlBulkInsertOperation
    {
        public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
        {
            return base.Execute(rows);
        }
    }

    static void Main(string[] args)
    {
        var x = new MyOverride();
        x.Execute(null);
    }
}
无言温柔 2024-10-03 02:45:27

您的示例无法编译,缺少一些返回,但以下修改后的示例

public class Row
{
}

public abstract class BaseDatabaseOperation
{
    public abstract IEnumerable<Row> Execute(IEnumerable<Row> rows);
}

public abstract class SqlBulkInsertOperation : BaseDatabaseOperation
{
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
    {
        Console.WriteLine("does useful work");
        return new Row[0];
    }
}

public class MyOverride : SqlBulkInsertOperation
{
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
{

        Console.WriteLine("do own work here");

    //This does not execute code in base class!
        base.Execute(rows);

        return new Row[0];
}
}

调用如下:

MyOverride mo = new MyOverride();
mo.Execute(new Row[0]);

生成输出

do own work here
does useful work

您必须执行示例中未包含的其他操作。

Your example does not compile, some returns are missing, but the following modified example

public class Row
{
}

public abstract class BaseDatabaseOperation
{
    public abstract IEnumerable<Row> Execute(IEnumerable<Row> rows);
}

public abstract class SqlBulkInsertOperation : BaseDatabaseOperation
{
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
    {
        Console.WriteLine("does useful work");
        return new Row[0];
    }
}

public class MyOverride : SqlBulkInsertOperation
{
    public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
{

        Console.WriteLine("do own work here");

    //This does not execute code in base class!
        base.Execute(rows);

        return new Row[0];
}
}

Called like this:

MyOverride mo = new MyOverride();
mo.Execute(new Row[0]);

generates the output

do own work here
does useful work

You must have done something else not included in your example.

守护在此方 2024-10-03 02:45:27

这些都是同时编译的吗?您可能会遭受断开连接的中间基类 http://blogs.msdn.com/b/ericlippert/archive/2010/03/29/putting-a-base-in-the-middle.aspx

are these all being compiled at the same time? you might be suffering from the disconnected middle base class http://blogs.msdn.com/b/ericlippert/archive/2010/03/29/putting-a-base-in-the-middle.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文