2

我有一个 C# 类,它具有一些我想允许该类的客户端覆盖的功能。具体来说,我想要以下内容:

  1. 如果客户端什么都不做,他们会得到我们的默认行为
  2. 客户端可以覆盖该行为并导致我们的默认行为被调用。
  3. 客户端可以覆盖该行为并导致我们的默认行为被称为前/后/中间操作。

我目前的想法是:

  1. 如果客户想要覆盖该行为,则公开一个客户将订阅的事件。
  2. 公开具有默认行为的方法(与事件的签名匹配): void DefaultBehavior()
  3. 每当我们尝试触发事件时,如果委托为空,我们调用我们的默认行为方法,否则,我们调用事件的委托:

    if (eventDelegate == null)
        DefaultBehavior();
    else
        eventDelegate();
    

当客户端覆盖行为时,他们可以选择调用我们的 DefaultBehavior 方法来获得所需的行为。

从客户的角度来看,您认为这种方法是否足够直观?或者您能提出任何可能更好的替代方案吗?

4

4 回答 4

8

好吧,如果您希望您的客户端覆盖某些行为,为什么不创建一个虚函数,让客户端实际override使用它呢?

这是实现这一点的直接方法。无需重新发明轮子。

于 2012-06-14T21:56:39.833 回答
2

如果我理解你的问题,client你的意思是一些代码调用你的类,而不是覆盖你的类,假设你需要这样做(如果你可以这样做,我同意@zmbq 的回答):

你可以让你的方法有 2 个重载,一个没有参数,另一个接收一个Action对象

public void methodName()
public void methodName(Action delegate)

然后在你的身体中,methodName()你会用 defaultAction 调用另一个方法

public void methodName()
{
  methodName(DefaultBehavior);
}

最后在第二种方法中,您只需调用作为参数传递的委托,而不关心它是否是默认值

public void methodName(Action delegate)
{
 delegate();
}

您班级的客户将看到这两个重载,并决定是使用默认行为还是提供自定义行为

编辑: 好的,最后一次尝试:),根据您的最后评论,您是否可以拥有一个实例字段

private Action behaviorDelegate = DefaultBehavior;

您可以在班级中的任何地方分配behaviorDelegate不同的行为,然后您不需要声明,因为无论是否为默认行为,if该行为将始终处于可变状态。delegate这不是一个很大的变化,但对我来说似乎更干净。

于 2012-06-14T22:00:56.060 回答
1

你也可以(也许?)在没有事件的情况下做到这一点:

宣言:

public class DemoClass
{
    public delegate string MyDelegate(string testValue);

    public static MyDelegate DefaultBehavior
    {
        get
        {
            return testValue => 
              { 
                 return String.Concat(testValue, 
                                      ", now with 99% more exclamation points!!!!!!!!"); 
              };
        }
    }

    public MyDelegate ModifyString = testValue => 
        { 
           return DemoClass.DefaultBehavior(testValue); 
        };
}

采用:

// first, default:
DemoClass demoObject = new DemoClass();
Console.WriteLine(demoObject.ModifyString("My test string")); 

// now, pure "override":
demoObject.ModifyString = testVal => 
        { return String.Concat(testVal, ", this time with question marks????"); 
        };
Console.WriteLine(demoObject.ModifyString("Second test string"));

// finally, define a delegate that overrides and calls default:
DemoClass.MyDelegate combined = testVal => 
        { return String.Concat(DemoClass.DefaultBehavior(testVal), 
                               ", now we're really tricky"); 
        };
demoObject.ModifyString = combined;
Console.WriteLine(demoObject.ModifyString("Third test string"));

输出:

我的测试字符串,现在多了 99% 的感叹号!!!!!!!!!
第二个测试字符串,这次带问号???
第三个测试字符串,现在有 99% 以上的感叹号!!!!!!!!!,现在我们真的很棘手
于 2012-07-16T19:48:03.730 回答
0

只需使用虚拟方法:

public class BaseClass {
   public virtual void Something() {
      Console.WriteLine("base functionality");
   }
}

public class Sub1 : BaseClass {
   public override void Something() {
       // do whatever you want here
       base.Something();  // don't call it at all if you like
       // do whatever you want here
   }
}
于 2012-06-14T22:12:18.977 回答