我发现Func<T> 在创建需要“即时”个性化的组件时非常有用。
举这个非常简单的例子:PrintListToConsole<T> 组件。
一个非常简单的对象,将这个对象列表打印到控制台。
您想让使用它的开发人员个性化输出。
比如你想让他定义一个特定类型的数字格式等等。
没有功能
首先,您必须为接受输入并生成要打印到控制台的字符串的类创建一个接口。
interface PrintListConsoleRender<T> {
String Render(T input);
}
然后您必须创建类PrintListToConsole<T>,该类采用先前创建的接口并在列表的每个元素上使用它。
class PrintListToConsole<T> {
private PrintListConsoleRender<T> _renderer;
public void SetRenderer(PrintListConsoleRender<T> r) {
// this is the point where I can personalize the render mechanism
_renderer = r;
}
public void PrintToConsole(List<T> list) {
foreach (var item in list) {
Console.Write(_renderer.Render(item));
}
}
}
需要使用您的组件的开发人员必须:
实现接口
-
将真实类传递给PrintListToConsole
class MyRenderer : PrintListConsoleRender<int> {
public String Render(int input) {
return "Number: " + input;
}
}
class Program {
static void Main(string[] args) {
var list = new List<int> { 1, 2, 3 };
var printer = new PrintListToConsole<int>();
printer.SetRenderer(new MyRenderer());
printer.PrintToConsole(list);
string result = Console.ReadLine();
}
}
使用 Func 更简单
在组件内部定义Func<T,String> 类型的参数,表示函数的接口,该函数接受T 类型的输入参数并返回字符串(控制台的输出)
class PrintListToConsole<T> {
private Func<T, String> _renderFunc;
public void SetRenderFunc(Func<T, String> r) {
// this is the point where I can set the render mechanism
_renderFunc = r;
}
public void Print(List<T> list) {
foreach (var item in list) {
Console.Write(_renderFunc(item));
}
}
}
当开发人员使用您的组件时,他只需将 Func<T, String> 类型的实现传递给组件,这是一个为控制台创建输出的函数。
class Program {
static void Main(string[] args) {
var list = new List<int> { 1, 2, 3 }; // should be a list as the method signature expects
var printer = new PrintListToConsole<int>();
printer.SetRenderFunc((o) => "Number:" + o);
printer.Print(list);
string result = Console.ReadLine();
}
}
Func<T> 可让您动态定义通用方法接口。
您定义输入是什么类型以及输出是什么类型。
简洁明了。