我有delegate
如下:
public delegate TestResult TestCase(byte[] source);
...返回TestResult
的位置如下:
public class TestResult {
public bool Pass { get; }
public int Index { get; }
public TestResult(bool result, int index) {
Pass = result;
Index = index;
}
}
示例TestCase
委托如下:
public static TestResult In(byte[] tkn, ITestSet testSet) {
return testSet.Contains(tkn);
}
ITestSet
只不过是封装的HashSet<byte[]>
。
在一个用例中,我有2个测试集:(1)A - z,(2)0 - 9.我想测试输入byte[]
是否在任一测试集中。
我正在使用Expression<TestCase>
,但无法弄清楚如何实施Or
测试用例。我有一个TestCaseBuilder
,其中包含以下方法:
public class TestCaseBuilder {
private Expression<TestCase> tcExpr;
public TestCaseBuilder With(TestCaseBuilder tcBuilder) {
tcExpr = tcBuilder.tcExpr;
return this;
}
public TestCaseBuilder Or(TestCaseBuilder tcBuilder) {
tcExpr = tcExpr.Or(tcBuilder.tcExpr);
return this;
}
}
...和我的扩展方法:
public static Expression<TestCase> Or (this Expression<TestCase> tcLeft, Expression<TestCase> tcRight) {
var lExpr = (LambdaExpression)tcLeft;
var rExpr = (LambdaExpression)tcRight;
var param = lExpr.Parameters;
return Expression.Lambda<TestCase>(/* what to do here ? */, param);
}
Expression.OrElse
机械上是我认为合适但不能使用的,因为我返回的是TestResult
,而不是bool
。
以下是TestCaseBuilder
的使用方式:
testcaseBuilder.As("Foo")
.With(isLetterTestCase)
.Or(isDigitTestCase);
我仅使用Or
代表执行TestCase
:
public static TestCase Or(this TestCase tc1, TestCase tc2) {
return tkn => {
var res = tc1(tkn);
if (res.Pass) {
return res;
}
return tc2(tkn);
};
}
如何在不调用第一个测试用例的情况下在自定义Expression<TestCase>
方法中合并2 Or
?
答案 0 :(得分:0)
这是你想要的吗
public static Expression<Func<byte[], TestResult, TestCase, TestResult>> helperExp = (inp, res, next) => res.Pass ? next(inp) : res;
public static Expression<TestCase> Or(Expression<TestCase> exp1, Expression<TestCase> exp2)
{
var param = exp1.Parameters;
Expression<TestCase> or = Expression.Lambda<TestCase>(
Expression.Invoke(helperExp,
param[0], Expression.Invoke(exp1, param), exp2),param);
return or;
}
使用块表达式无需调用
public static Expression<TestCase> Or(Expression<TestCase> exp1, Expression<TestCase> exp2)
{
var param = exp1.Parameters;
ParameterExpression local = Expression.Parameter(typeof(TestResult), "local");
BlockExpression block = Expression.Block(
new[] { local },
Expression.Assign(local, exp1.Body),
Expression.Condition(Expression.Property(local, nameof(TestResult.Pass)), exp2.Body, local));
return Expression.Lambda<TestCase>(block, param);
}
测试
Expression<TestCase> exp1 = (tc) => new TestResult(true);
Expression<TestCase> exp2 = (tc) => new TestResult(false);
var first = Or(exp1, exp1);
var second = Or(first, exp2);
var func = second.Compile();
var result = func(new byte[] { });
使用https://github.com/louthy/csharp-monad可能有更好的方法来执行没有表达式的条件monad 我的.net核心使用monad原则用于中间件。