根据MSDN,建议在需要简单构图时使用代表。 有人可以用一个例子来解释 Easy Composition 是什么?
答案 0 :(得分:2)
这篇MSDN文章比较了某些情况下接口的使用情况与代表的使用情况。它表示代表与界面相比提供了简单的组合。这是什么意思?假设你有这样的界面:
interface ICanWrite {
void Write();
}
现在你有两个这样的接口实例:
ICanWrite first;
ICanWrite second;
你是如何撰写的?那么,您如何获得ICanWrite
个Write
方法同时执行first.Write
和second.Write
的新static void Main(String[] args)
{
Action write = null; // Action is a delegate type
write += () => Console.WriteLine("one"); // first write
write += () => Console.WriteLine("two"); // composition, looks quite easy compared to interfaces
write(); // both delegates are executed ("one two")
}
实例?不容易。
现在假设您使用委托而不是接口:
click
答案 1 :(得分:2)
一个例子会有所帮助。
想象一下,您有一个需要输出一些日志消息的类,并且您希望使用构造函数依赖注入为该类提供记录消息的方法。
您有多种选择,包括:
界面可能如下所示:
public interface Log
{
void WriteLine(string message);
// ... Other methods
}
因此课程可能如下所示:
public sealed class MyClass
{
readonly ILog _log;
public MyClass(ILog log)
{
_log = log;
}
public void Test()
{
_log.WriteLine("Test() called");
}
}
此类现在耦合到ILog
接口,在构造它时,您必须提供一个实现ILog
的对象。
如果您使用委托,则该类可能如下所示:
public sealed class MyClass
{
readonly Action<string> _writeLogLine;
public MyClass(Action<string> writeLogLine)
{
_writeLogLine = writeLogLine;
}
public void Test()
{
_writeLogLine("Test() called");
}
}
现在该类不再与ILog
耦合,并且在构造它时,您可以将与该委托匹配的任何方法传递给它:
var myClass = new MyClass(Console.WriteLine);
这使MyClass
的构图更容易 - 因此 轻松构图 。
答案 2 :(得分:1)
你误解了#34;容易构图&#34; as&#34; Easy Composition&#34;,实际上它并不意味着它本身就是一个技术术语。它们只是意味着使用代理比使用接口更容易实现组合(即需要更少的工作)。
如果您已经成为.NET程序员一段时间,您可能会认识System.Action
代表。您可以一瞥MSDN文章在将System.Action
与界面的外观进行比较时的含义:
delegate void Action();
interface IAction
{
void Execute();
}
代表是一个单行,而界面需要更多的输入,并且需要为该方法提供一个额外的名称。
MSDN文章的真正含义是使用委托与接口。我们假设您有一些采用回调处理程序的方法onCompleted
:
void DoSomethingThatTakesVeryLong(Action onCompleted)
{
// do something that might take a while:
…
// notify the caller that we're done:
onCompleted();
}
现在使用这种方法需要什么?
如果onCompleted
属于委托类型,您可以编写以下内容:
DoSomethingThatTakesVeryLong(() => Console.WriteLine("Done."));
如果onCompleted
属于接口类型(让我们假定上面是IAction
),那么您必须将回调代码包装在实现IAction
的类型中:
class DoneLogger : IAction
{
public void Execute()
{
Console.WriteLine("Done");
}
}
DoSomethingThatTakesVeryLong(new DoneLogger());
这需要做更多的工作:你需要在一个非常必要的类中包含非常简单的代码,你需要为该类提供一个名称,你需要实例化该类。现在想象一下,没有代表,你总是必须这样做......那就是很多样板代码。
我希望这能帮助您了解代表如何比接口更少的工作。