如何在 C# 中泛化委托
本文关键字:泛化 | 更新日期: 2023-09-27 18:35:49
我正在尝试创建一个类似于以下内容的委托序列生成器(这对于单元测试中的存根很有用):
public class StubSequenceBuilder<T>
{
private readonly Queue<Func<T>> _sequenceQueue = new Queue<Func<T>>();
public StubSequenceBuilder<T> Next(Func<T> func)
{
_sequenceQueue.Enqueue(func);
return this;
}
public Func<T> Build()
{
return () =>
{
var func = _sequenceQueue.Dequeue();
return func();
};
}
}
序列生成器创建一个Func<T>
,该每次调用时都返回不同的值。
但是,这仅适用于没有参数并返回值的委托。有没有办法泛化这个类以支持任何委托?
我知道类型约束不支持委托;C# 中还有其他东西可以用来实现这一点吗?
C# 中没有任何直接方法可以做到这一点,但您可以使用类似于以下文本模板 (*.tt) 的内容:
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ output extension=".cs" #>
using System;
using System.Linq;
using System.Collections.Generic;
<#
var maxArguments = 5;
for(int i=0; i < maxArguments; ++i) {
var argTypes = string.Join(", ",new string[i+1].Select((x,j)=>"T"+j).ToArray());
#>
public class StubSequenceBuilder<<#= argTypes #>>
{
private readonly Queue<Func<<#= argTypes #>>> _sequenceQueue = new Queue<Func<<#= argTypes #>>>();
public StubSequenceBuilder<<#= argTypes #>> Next(Func<<#= argTypes #>> func)
{
_sequenceQueue.Enqueue(func);
return this;
}
//...
}
<# } #>
输出 (*.cs):
using System;
using System.Linq;
using System.Collections.Generic;
public class StubSequenceBuilder<T0>
{
private readonly Queue<Func<T0>> _sequenceQueue = new Queue<Func<T0>>();
public StubSequenceBuilder<T0> Next(Func<T0> func)
{
_sequenceQueue.Enqueue(func);
return this;
}
//...
}
public class StubSequenceBuilder<T0, T1>
{
private readonly Queue<Func<T0, T1>> _sequenceQueue = new Queue<Func<T0, T1>>();
public StubSequenceBuilder<T0, T1> Next(Func<T0, T1> func)
{
_sequenceQueue.Enqueue(func);
return this;
}
//...
}
//...