共通言語ランタイムが無効なプログラムを検出する結果となる.NET4.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");
}
}
}
注:プロジェクトをビルドするには、.NETFramework4.0のアセンブリSystem.Windows.Forms.dllを参照する必要があります。
背景情報
サードパーティが出荷する低レベルのテスト自動化ツール(サードパーティのツールを使用して高抽象化レベルのキーワード駆動型スクリプトを実行する自動化フレームワーク)を使用して、高抽象化レベルのスクリプト処理キーワード駆動型テスト自動化フレームワークを開発します。下位レベルのグラフィックUIへのアクセス)。均一な値の検証アプローチを実装するには、上記の構造が必要です。
リストされたコードの各要素は、次のことを表しています。
- Tst1-値を検証するためのクラス
- メソッド1 -UI(ユーザーインターフェイス)から取得されている値の検証を実行し、UI要素が必要な値を取得するまで待機するタイムアウトを受け入れることができるポリモーフィックメソッド
- TstBase-サードパーティの低レベル自動化ツールAPIから処理するすべてのUIコントロールの基本クラス
- Tst2-サードパーティの低レベル自動化ツールAPIから特定のタイプのコントロールを処理するためのクラス
- ExtensionMethod-サードパーティの低レベル自動化ツールAPIの任意のcontrol-handler-classのインスタンスを使用して、すべてのタイプのコントロールからテキストを取得するためのジェネリックメソッド
Method1は、test-script-stepパラメーターから値を取得し、すぐにそれを利用する他のメソッドに引数として渡されるデリゲートを返します。全体として、次のようになります。
testStepParameters.MakeUseOf("Field1ExpectedValue", validation.Verify<string>(field1.GetValue));
最初のコードスニペットからでvalidation.Verify<string>(field1.GetValue)
はなく、どこに行くか。tst1.Method1<string>(tst2.ExtensionMethod)
重要なお知らせ
欠陥の回避策を1つ見つけましたが、コードにある程度の不器用さが追加されるため、私はそれが好きではありません。私が見つけた回避策は、拡張メソッドの直接使用を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
拡張メソッドの実装)。