“公共语言运行时检测到无效程序”需要解决此问题。为generi方法抛出的异常

时间:2012-08-22 15:16:27

标签: c# .net generics delegates extension-methods

您能否建议解决 .NET 4.0 defect,这会导致公共语言运行时检测到无效程序。例程在启动以下程序时在Visual Studio 2010中):

注意:在Visual Studion 2012中编译相同程序时,行为无法重现。

namespace Namespace1
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    public class Tst1
    {
        public Action<DataType> Method1<DataType>(Func<DataType> param1) { return this.Method1<DataType>(param1, 0); }
        public Action<DataType> Method1<DataType>(Func<DataType> param1, int param2)
        {
            return param => System.Windows.Forms.MessageBox.Show(param1().ToString() + " " + param.ToString());
        }
    }

    public class TstBase { }

    public class Tst2 : TstBase { }

    public static class TstExtensions
    {
        public static string ExtensionMethod<TstType>(this TstType tst)
            where TstType : TstBase
        {
            return "From extension method";
        }
    }

    public class Application
    {
        public static void Main()
        {
            Tst1 tst1 = new Tst1();
            Tst2 tst2 = new Tst2();

            tst1.Method1<string>(tst2.ExtensionMethod)("From main");
        }
    }
}

注意:需要引用.NET Framework 4.0的程序集 System.Windows.Forms.dll 来构建项目。

背景资料

我在第三方发布的低级测试自动化工具上开发高抽象级脚本处理关键字驱动的测试自动化框架(自动化框架在第三方执行高抽象级别的关键字驱动脚本用于访问较低级别的图形UI的工具)。上面列出的结构需要实施统一的价值验证方法。

列出的代码的每个元素代表以下内容:

  • Tst1 - 用于验证值的类
  • Method1 - 执行从UI(用户界面)检索的值的验证并且可以接受超时以等待UI元素获取所需值的多态方法
  • TstBase - 从第三方低级自动化工具API处理的所有UI控件的基类
  • Tst2 - 用于处理来自第3方低级自动化工具API的某些类型控件的类
  • ExtensionMethod - 使用来自第3方低级自动化工具API的任何控制处理程序类的实例从所有类型的控件检索文本的通用方法

Method1返回委托,该委托作为参数传递给从test-script-step参数检索值的其他方法,并立即使用它。总而言之,它看起来像是:

testStepParameters.MakeUseOf("Field1ExpectedValue", validation.Verify<string>(field1.GetValue));

其中validation.Verify<string>(field1.GetValue)代替tst1.Method1<string>(tst2.ExtensionMethod)来自第一个代码段。

重要通知

我发现了一个解决缺陷的方法,但我不喜欢它,因为它增加了代码的某种程度的笨拙。我找到的解决方法是用 Lambda 表达式替换扩展方法的直接使用 - 即在行时bug不会重现:

tst1.Method1<string>(tst2.ExtensionMethod)("From main");

替换为line:

tst1.Method1<string>(() => tst2.ExtensionMethod())("From main");

最终形式如下:

testStepParameters.MakeUseOf("Field1ExpectedValue", validation.Verify<string>(() => field1.GetValue()));

当代替field1变量用于检索控件的复杂调用(可能是委托返回控件)时,使用该变通办法变得完全不愉快 - 这对于检查控制状态随着时间的推移特别有用而不会烦恼如何检索控件 - 使用自己的GetValue扩展方法实现。

1 个答案:

答案 0 :(得分:1)

您可以通过自己创建委托来修复它,而不是让C#为您完成。像这样:

 tst1.Method1<string>(new Func<string>(tst2.ExtensionMethod))("From main");