运行时检查Func委托

时间:2009-12-29 06:24:17

标签: c#

请考虑以下代码段:

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委托并且仍然可以实现这一目标的方式很简单。
感谢。

1 个答案:

答案 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);        
    }
}

如果只计算一次计算,这将是一个不错的选择。