有没有一种方法可以通过自动调用基本方法来扩展方法,而不用用C#编写调用?
我希望在应该扩展的类中有一个调试记录器。有没有一种方法可以做到这一点,而不必在每个派生类上添加日志条目有没有一种方法可以通过自动调用基本方法来扩展方法,而不用用C#编写调用?,c#,polymorphism,overriding,virtual-functions,method-call,C#,Polymorphism,Overriding,Virtual Functions,Method Call,我希望在应该扩展的类中有一个调试记录器。有没有一种方法可以做到这一点,而不必在每个派生类上添加日志条目 using System; public abstract class Phase { public virtual void Start() { Console.Write("[LOG] Start"); } /// <summary> /// Returns true when finished.
using System;
public abstract class Phase {
public virtual void Start() {
Console.Write("[LOG] Start");
}
/// <summary>
/// Returns true when finished.
/// </summary>
public virtual bool Update() {
Console.Write("[LOG] Update");
return true;
}
public virtual void End() {
Console.Write("[LOG] End");
}
}
public class PhaseMenu : Phase {
private byte _counter;
public override void Start() {
_counter = 0;
}
public override bool Update() {
_counter++;
if ( _counter > 100 ) {
return true;
}
return false;
}
public override void End() {
}
}
使用系统;
公共抽象类阶段{
公共虚拟void Start(){
Console.Write(“[LOG]Start”);
}
///
///完成时返回true。
///
公共虚拟bool更新(){
Console.Write(“[LOG]Update”);
返回true;
}
公共虚拟void End(){
Console.Write(“[LOG]End”);
}
}
公共类阶段:阶段{
专用字节计数器;
公共覆盖无效开始(){
_计数器=0;
}
公共覆盖布尔更新(){
_计数器++;
如果(_计数器>100){
返回true;
}
返回false;
}
公共覆盖无效结束(){
}
}
期望的结果是在调用PhaseMenu的方法时编写日志。因此,这些方法不是重写,而是扩展。阅读您的问题和相关评论,我能想到的唯一出路是实现某种基于结构的方法。这不仅仅是编写base.Log()的麻烦,但它可能会为您带来好处 基本上你可以订阅每一个方法到一个事件或者类似的事件日志中。这将自动完成 此外,事件订阅可以通过编程方式(通过或其他方式)完成,因此只需几行代码 编辑:
这是一个通过反射解决问题的示例,Dorjan可能也是一个想法:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var phaseMenu = new PhaseMenu();
phaseMenu.Start();
phaseMenu.Update();
phaseMenu.Update();
phaseMenu.Update();
phaseMenu.End();
}
}
public abstract class Phase
{
private readonly Action _onStart;
private readonly Func<bool> _onUpdated;
private readonly Action _onEnd;
protected Phase(Action aOnStart, Func<bool> aOnUpdated, Action aOnEnd)
{
_onStart = aOnStart;
_onUpdated = aOnUpdated;
_onEnd = aOnEnd;
}
public void Start()
{
Console.WriteLine("[LOG] Start");
_onStart?.Invoke();
}
public bool Update()
{
Console.WriteLine("[LOG] Update");
return _onUpdated?.Invoke() ?? false;
}
public void End()
{
Console.WriteLine("[LOG] End");
_onEnd?.Invoke();
}
}
public class PhaseMenu : Phase
{
private static byte _counter;
public PhaseMenu() : base(OnStart, OnUpdated, OnEnd)
{ }
private static void OnStart()
{
_counter = 0;
}
private static bool OnUpdated()
{
_counter++;
return _counter > 100;
}
private static void OnEnd()
{
Console.WriteLine("That is all folks!");
}
}
其思想是,您的基类实现某种契约,让其实现者“遵循”。我给出的一个示例仅限于提供实现的某些方法,但您始终可以提供一个方法来“注册”这些方法的行为
我认为这可以进一步改进,这取决于需要和需要实现的目标,但希望这也能让我了解我的想法
编辑:
我刚刚看到了关于事件的想法,所以这是它的一个简化实现。不要在基类中将更新方法定义为virtual,然后使用一个新的受保护的虚拟(或抽象)方法,称为PhaseUpdate(),您可以在Update中调用它。从而强制所有调用通过基方法更新
using System;
public abstract class Phase {
public void Start() {
Console.Write("[LOG] Start");
PhaseStart();
}
/// <summary>
/// Returns true when finished.
/// </summary>
public bool Update() {
Console.Write("[LOG] Update");
return PhaseUpdate();
}
public void End() {
Console.Write("[LOG] End");
PhaseEnd();
}
protected void PhaseStart() {
}
/// <summary>
/// Returns true when finished.
/// </summary>
protected virtual bool PhaseUpdate() {
return true;
}
protected virtual void PhaseEnd() {
}
}
public class PhaseMenu : Phase {
private byte _counter;
protected override void PhaseStart() {
_counter = 0;
}
protected override bool PhaseUpdate() {
_counter++;
if ( _counter > 100 ) {
return true;
}
return false;
}
protected override void PhaseEnd() {
}
}
使用系统;
公共抽象类阶段{
公开作废开始(){
Console.Write(“[LOG]Start”);
相位启动();
}
///
///完成时返回true。
///
公共bool更新(){
Console.Write(“[LOG]Update”);
返回相更新();
}
公共无效结束(){
Console.Write(“[LOG]End”);
相位();
}
受保护的无效PhaseStart(){
}
///
///完成时返回true。
///
受保护的虚拟布尔相更新(){
返回true;
}
受保护的虚拟空阶段(){
}
}
公共类阶段:阶段{
专用字节计数器;
受保护的覆盖无效PhaseStart(){
_计数器=0;
}
受保护的覆盖布尔相位更新(){
_计数器++;
如果(_计数器>100){
返回true;
}
返回false;
}
受保护的覆盖无效阶段(){
}
}
您是否没有忘记从PhaseMenu
调用base.Start()?我想知道是否有一种方法可以做到这一点,而不必在每个方法上都编写base.me()?不,我知道。您使用虚拟性,这就是:您需要调用base来传播行为,或者不调用base来破坏行为。我希望这能帮助你享受C#编码:你是说在C#中根本没有办法做到这一点吗?或者如果我用虚拟的?我明白虚拟现实是不可能的,所以我的问题是,是否有更好的方法。如果我不清楚我的任命?好的。很高兴知道。非常感谢。如果你的回答是“不,但是你可以使用Base.MethodName()”,我会标记为正确。事实上,如果事件的使用符合OP的目标,它可能会提供所需的链式处理程序方法池:处理程序执行我想回答,我已经看到了这一点,但需要离开办公桌几个小时。我以前考虑过事件,但我会阅读文章,看看它是否能激发出一个合适的解决方案。谢谢。哦,我明白了,所以我使用反射设置了一个日志类,该类将采用一种类型,并根据触发的事件记录详细信息。你是对的,这可能是过度工程化的,但可能是需要考虑的。@Dorjan是的,我在我的答案中添加了一个链接,这可能有助于理解如何通过思考解决问题。如果有帮助,请将其标记为答案。感谢您提供了它在事件中的外观示例。我会用不同的解决方案玩一玩没问题。祝你好运;)
using System;
public abstract class Phase {
public void Start() {
Console.Write("[LOG] Start");
PhaseStart();
}
/// <summary>
/// Returns true when finished.
/// </summary>
public bool Update() {
Console.Write("[LOG] Update");
return PhaseUpdate();
}
public void End() {
Console.Write("[LOG] End");
PhaseEnd();
}
protected void PhaseStart() {
}
/// <summary>
/// Returns true when finished.
/// </summary>
protected virtual bool PhaseUpdate() {
return true;
}
protected virtual void PhaseEnd() {
}
}
public class PhaseMenu : Phase {
private byte _counter;
protected override void PhaseStart() {
_counter = 0;
}
protected override bool PhaseUpdate() {
_counter++;
if ( _counter > 100 ) {
return true;
}
return false;
}
protected override void PhaseEnd() {
}
}