c# – 使用“base”关键字时不执行的基类方法中的代码
当重写一个抽象方法并尝试调用我目前正在覆盖的基类方法时,我发现了一个非常奇怪的问题.
//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. 我错过了什么? 解决方法
编辑:我发现了这个问题……具有讽刺意味的是,我对Eric的“心灵调试”评论并没有那么遥远,给出了
this blog post.这是一个简短但完整的程序,它将展示正在发生的事情……
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]); } } 这将打印“在MyOverride.Execute”,但它*不会“打印”在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()…所以方法的主体永远不会被执行. 有关详细信息,请参见my article on iterator blocks,part two of Eric’s blog post或从home page of the first edition of C# in Depth下载第6章(第6章介绍迭代器块,并且是免费的). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |