無関係なクラスに同じ名前の長時間実行タスクがあります。私はこのコードを動的を使用する一般的な方法で使用しようとしていました。次のエラーが発生します
Microsoft.CSharp.RuntimeBinder.RuntimeBinderExceptionはユーザーコードによって処理されませんでしたMessage =タイプ「void」を「オブジェクト」に暗黙的に変換できません
コードを次のように分離しようとしました
class Program
{
static void Main(string[] args)
{
MainAsync();
Console.ReadKey();
}
static async void MainAsync()
{
var classA = new ClassA();
var classB = new ClassB();
await RunTask1(classA);
await RunTask1(classB);
await RunTask(classA);
await RunTask(classB);
}
static async Task RunTask(dynamic val)
{
await Task.Run(() => val.CommonLongRunningTask());
}
static async Task RunTask1(ClassA val)
{
await Task.Run(() => val.CommonLongRunningTask());
}
static async Task RunTask1(ClassB val)
{
await Task.Run(() => val.CommonLongRunningTask());
}
}
internal class ClassA
{
public void CommonLongRunningTask()
{
Console.WriteLine("Class A CommonLongRunningTask");
}
}
internal class ClassB
{
public void CommonLongRunningTask()
{
Console.WriteLine("Class B CommonLongRunningTask");
}
}
動的ではなくオブジェクト自体(RunTask1)を渡すと、機能します。私はダイナミックに通過しているときに何が起こっているのかを理解しようとしています。
言語内の何かまで追跡することはまだできていませんが、動的式を使用した式ラムダを使用できないようです。 更新:voidメソッド呼び出しがあるかどうかに関係なく、を含む式dynamic
は常に型です。言語アスペクトの更新をdynamic
参照してください。
ステートメントラムダは機能します:
private static async Task RunTask(dynamic val)
{
await Task.Run(() =>
{
val.CommonLongRunningTask();
});
}
事実上、ここで起こっていることは、コンパイラーがこれに遭遇したときです。
() => val.CommonLongRunningTask()
それはそれで以下と同等であると解釈します:
() => {return val.CommonLongRunningTask();}
...コンパイル時に、呼び出したものが何も返さないことを知らval
ないためです。実行時に、val.CommonLongRunningTask()
型はあるvoid
がreturn
最小公分母に対してもその値をとることができない式に遭遇し、object
メッセージとともに例外をスローします。Cannot implicitly convert type 'void' to 'object'
RunTask
次のように書き直した場合も、まったく同じ例外が発生します。
private static async Task RunTask(dynamic val)
{
await Task.Run(() =>
{
return val.CommonLongRunningTask();
});
}
もう少し調査/議論した後、C#仕様のセクション7.5.2に、これが発生する理由が詳しく説明されているようです。基本的に、動的に関係するものはすべてそれ自体が動的型であり(コンパイル時にコンパイラーはバインド方法を認識できないため)、したがって「val.CommonLongRunningTask()」を動的を返すものと見なします(したがって、実行時エラーが発生します)。実行時に無効であることに気付いたとき)。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加