2

您能否建议解决导致公共语言运行时检测到无效程序的.NET 4.0 缺陷。启动以下程序时出现异常(在 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的Assembly System.Windows.Forms.dll 。

背景资料

我在 3-rd 方提供的低级测试自动化工具上开发了高抽象级脚本处理关键字驱动的测试自动化框架(自动化框架,它使用 3-rd 方工具执行高抽象级别的关键字驱动脚本访问较低级别的图形 UI)。上面列出的构造是实施统一值验证方法所必需的。

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

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

Method1 返回委托,该委托作为参数传递给从测试脚本步骤参数中检索值并立即使用它的其他方法。总而言之,它如下所示:

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

wherevalidation.Verify<string>(field1.GetValue)去而不是tst1.Method1<string>(tst2.ExtensionMethod)从第一个代码片段开始。

重要通知

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

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

替换为行:

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

在最终形式中,它看起来像:

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

并且当使用复杂的调用而不是field1变量来检索控制(可能是委托返回控制)时,这种变通方法的使用变得完全不愉快(这对于随着时间的推移检查控制状态而不用担心如何检索控制特别有用)GetValue扩展方法的实现)。

4

1 回答 1

1

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

 tst1.Method1<string>(new Func<string>(tst2.ExtensionMethod))("From main");
于 2012-08-22T15:36:07.407 回答