我同意@usr - 我认为空函数没有问题。如果你想调用一个函数,那么它必须存在。如果它在某些情况下什么都不做,那么该函数应该是空的。具有空函数的基类与需要一遍又一遍地实现相同空函数的接口相比,似乎是一个非常好的主意。
如果您正在寻找替代方案,您可以考虑责任链设计模式。您可以调用通用函数,然后参数化所需的行为,而不是调用特定函数。然后,您可以将对象链接在一起(不同情况下的不同链)并让它们都有机会处理行为。如果他们都没有处理它,那么什么都不会发生。
这在某些情况下会很好地工作,但实现起来比非常简单和优雅的基类方法更复杂。注意不要过度设计。
示例
根据您在问题中给出的示例,这是一个实现命令链的示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2 {
interface ICommand {
bool Execute( string action, params object[] parameters );
}
class Program {
static void Main( string[] args ) {
CommandChain l_chain1 = new CommandChain( new FirstCommand(), new SecondCommand() );
CommandChain l_chain2 = new CommandChain( new SecondCommand(), new ThirdCommand() );
// Chain 1
if ( l_chain1.Execute( "first", (int) 1, (double) 1.1 ) )
Console.WriteLine( "Chain 1 executed First" );
else
Console.WriteLine( "Chain 1 did not execute First" );
if ( l_chain1.Execute( "second", (double) 1.2 ) )
Console.WriteLine( "Chain 1 executed Second" );
else
Console.WriteLine( "Chain 1 did not execute Second" );
if ( l_chain1.Execute( "third", "4", (int) 3 ) )
Console.WriteLine( "Chain 1 executed Third" );
else
Console.WriteLine( "Chain 1 did not execute Third" );
// Chain 2
if ( l_chain2.Execute( "first", (int) 1, (double) 1.1 ) )
Console.WriteLine( "Chain 2 executed First" );
else
Console.WriteLine( "Chain 2 did not execute First" );
if ( l_chain2.Execute( "second", (double) 1.2 ) )
Console.WriteLine( "Chain 2 executed Second" );
else
Console.WriteLine( "Chain 2 did not execute Second" );
if ( l_chain2.Execute( "third", "4", (int) 3 ) )
Console.WriteLine( "Chain 2 executed Third" );
else
Console.WriteLine( "Chain 2 did not execute Third" );
Console.ReadKey( true );
}
}
class CommandChain {
private ICommand[] _commands;
public CommandChain( params ICommand[] commands ) {
_commands = commands;
}
public bool Execute( string action, params object[] parameters ) {
foreach ( ICommand l_command in _commands ) {
if ( l_command.Execute( action, parameters ) )
return true;
}
return false;
}
}
class FirstCommand : ICommand {
public bool Execute( string action, params object[] parameters ) {
if ( action == "first" &&
parameters.Length == 2 &&
parameters[0].GetType() == typeof( int ) &&
parameters[1].GetType() == typeof( double ) ) {
int i = (int) parameters[0];
double d = (double) parameters[1];
// do something
return true;
} else
return false;
}
}
class SecondCommand : ICommand {
public bool Execute( string action, params object[] parameters ) {
if ( action == "second" &&
parameters.Length == 1 &&
parameters[0].GetType() == typeof( double ) ) {
double d = (double) parameters[0];
// do something
return true;
} else
return false;
}
}
class ThirdCommand : ICommand {
public bool Execute( string action, params object[] parameters ) {
if ( action == "third" &&
parameters.Length == 2 &&
parameters[0].GetType() == typeof( string ) &&
parameters[1].GetType() == typeof( int ) ) {
string s = (string) parameters[0];
int i = (int) parameters[1];
// do something
return true;
} else
return false;
}
}
}
(请注意,此示例并未遵循所有编程最佳实践 - 我不建议完全实现此代码。例如,action 参数作为枚举可能比字符串更好,并返回某种 CommandResult 而不是布尔值. 仅用于灵感。)