Rozważmy następujący:Dlaczego każde oddzielne wywołanie dynamiczne powoduje dwa wyjątki i czy można je zignorować?
using System;
using System.Dynamic;
using System.Linq;
namespace DynamicObjectTest
{
class Program
{
static void Main(string[] args)
{
dynamic dyn = new TestDynamic();
Console.ReadKey();
foreach (var i in Enumerable.Range(0, 100))
{
Console.WriteLine(dyn.Foo());
Console.WriteLine(dyn.Bar());
}
Console.ReadKey();
}
}
class TestDynamic : DynamicObject
{
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (binder.Name == "Foo")
{
result = "Bar";
return true;
}
else if (binder.Name == "Bar")
{
result = "Foo";
return true;
}
return base.TryInvokeMember(binder, args, out result);
}
}
}
Po uruchomieniu tego programu, cztery wyjątki typu RuntimeBinderException
są wyrzucane. Można zaobserwować to zarówno poprzez złamanie wszystkich wyrzuconych wyjątkami (Debug/wyjątki .../sprawdzić wyjątków Common Language Runtime Rzut wyboru) lub przy użyciu perfmon:
Teraz te są oczywiście wyjątki złowione i poddane obróbce wewnętrznie, ponieważ metoda TryInvokeMember
jest wywoływana później. Wydaje się jednak, że jest to bardzo uciążliwe i niewłaściwe korzystanie z wyjątków, jeśli subskrybujesz mantrę "używaj wyjątków tylko w wyjątkowych okolicznościach". Dla mojego konkretnego przykładu to naprawdę nie problem, ponieważ ci sami członkowie - Foo
i Bar
- są wielokrotnie wywoływani. Mam jednak na myśli inne scenariusze, w których członkowie są znacznie mniej statyczni.
Czy jest coś, co można zrobić, aby środowisko wykonawcze wywołało TryInvokeMember
, nie rzucając żadnych wyjątków?
Istnieje pewna wewnętrzna wyjątkowa sprawa, że połykają. Możesz zdekodować kod 'TryInvokeMember', aby zobaczyć, co się dzieje. – Polynomial
Jeśli użyję checkboxa/rzuconego podejścia, to tak naprawdę nie będzie dla mnie łamać. –
@ Polinomial: Zwróciłem uwagę, że to jest wewnętrzne w moim pytaniu, ale to nie jest moje pytanie. –