有效地检查一个COM属性是否可用而不需要try/catch

本文关键字:不需要 try catch 是否 属性 检查 COM 一个 有效地 | 更新日期: 2023-09-27 18:03:55

我正在使用VSTO,并想检查某个属性是否在COM对象中可用。当它可用时,它将返回一个结果,当它不可用时,它将返回一个异常。

捕获com异常非常慢,我想知道是否有一种更有效的方法来检查该属性是否会抛出异常。

请注意,这个问题是类似的,但没有解决方案:如何检查一个COM属性或方法是否存在而不产生异常?

请注意,还有另一种检查范围是否有验证的方法,即使用range。SpecialCells,但我正在寻找检测COM对象中的属性是否可用的更通用的解决方案,因为同样的性能问题发生在其他Excel COM对象。

举例。如果一个范围有数据验证,range . validate . type属性将返回一个结果,如果它没有数据验证,那么它将抛出一个异常。下面的代码对有或没有数据验证的单元格进行了10次数据验证测试。在我的计算机上,测试一个具有数据验证输出的单元格的时间为0毫秒,而没有数据验证输出的单元格的时间超过500毫秒。

    public static bool HasDataValidation(Excel.Range range)
    {
        try
        {
            var validationType = range.Validation.Type;
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }
    public static void RunTest()
    {
        var excelApp = Globals.ThisAddIn.Application;
        var worksheet = (Excel.Worksheet) excelApp.ActiveSheet;
        var rangeWithoutDataValidation = worksheet.Range["A1"];
        var rangeWithDataValidation = worksheet.Range["A2"];
        rangeWithoutDataValidation.Validation.Delete();
        rangeWithDataValidation.Validation.Delete();
        rangeWithDataValidation.Validation.Add(Excel.XlDVType.xlValidateList, Excel.XlDVAlertStyle.xlValidAlertStop,
            Excel.XlFormatConditionOperator.xlBetween, "A,B,C");
        var watch = Stopwatch.StartNew();
        for (int i = 0; i < 10; i++)
        {
            bool hasValidation = HasDataValidation(rangeWithoutDataValidation);
        }
        watch.Stop();
        long timeNoValidation = watch.ElapsedMilliseconds;
        watch = Stopwatch.StartNew();
        for (int i = 0; i < 10; i++)
        {
            bool hasValidation = HasDataValidation(rangeWithDataValidation);
        }
        watch.Stop();
        long timeWithValidation = watch.ElapsedMilliseconds;
        MessageBox.Show(String.Format("Time without validation was {0} milliseconds.'nTime with validation was {1} milliseconds.", timeNoValidation,timeWithValidation));
    }

有效地检查一个COM属性是否可用而不需要try/catch

这样如何:

public static bool HasDataValidation(Excel.Range range)
{
    try
    {
        var validation = range.Validation;
        return (validation != null);
    }
    catch (Exception)
    {
        return false;
    }
}