请考虑以下代码段:
class Test
{
public int Length{ get; set; }
public Func<List<int>, double> Calculate { get; set; }
public void DoStuff(List<int> list)
{
// ... do some processing here ...
double ans = Calculate(list);
// ... do some more stuff ......
}
}
现在,我已经意识到将附加到Calculate属性的典型匿名Func委托将与Test类的Length属性以及传递给它的列表长度有关。代表。对于这两个长度之间的某些关系(例如,this.Length&lt; list.Count),我应该能够抛出异常。但是,这必须在运行时发生,并且我无法控制此类的用户将在Calculate属性中添加为委托的内容。
怎么做?我可以在Calculate属性的set方法中执行某些操作吗?如何在运行时检查是否满足涉及Test类的Length属性的某些条件以及传递给委托的列表对象的长度(计数)?
我还会考虑Test类的设计更改来实现我的目标(运行时检查),但是用户附加Func委托并且仍然可以实现这一目标的方式很简单。
感谢。
答案 0 :(得分:2)
在调用提供的委托之前添加自己的检查。这样,您可以在调用之前检查满足所有要求,并在一个地方完成检查(而不是在每个实现中重复)。
public void DoStuff(List<int> list)
{
CheckPreconditions(list);
double ans = Calculate(list);
}
private void CheckPreconditions(List<int> list)
{
if(list == null)
// throw ...
if(list.Length == 0)
// throw ...
if(Length < list.Count)
throw ArgumentException("list",
"list must have blah blah blah to satisfy requirements");
}
这类似于template method pattern,除了使用继承而不是委托用户提供的函数:)
此外,如果您使用计算字段而不是公共属性,则可以强制它通过DoStuff方法执行,因此将始终执行检查。
类似的东西:
class Test
{
public int Length{ get; set; }
private Func<List<int>, double> m_calculate;
// Inject into ctor
public Test(Func<List<int>, double> calculate)
{
if(calculate == null) throw new ArgumentNullException("calculate");
m_calculate = calculate;
}
// all access to Calculate is now through this method
public void DoStuff(List<int> list)
{
CheckPreconditions(list);
double ans = m_calculate(list);
}
}
如果只计算一次计算,这将是一个不错的选择。