Si è verificato un problema di runtime dopo alcuni refactoring e si è bloccato fino alla seguente situazione.Il passaggio di un parametro dinamico genera RuntimeBinderException quando si chiama Method dall'interfaccia ereditata
Quando si passa una proprietà da un oggetto dinamico a un metodo su un'interfaccia ereditata da un'interfaccia padre, il raccoglitore di runtime non è in grado di trovare il metodo.
Ecco un test per dimostrare sia il fallimento e il successo (quando si chiama il metodo direttamente sul tipo di interfaccia madre)
using System.Dynamic;
using Microsoft.CSharp.RuntimeBinder;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Test.Utility
{
public interface IEcho
{
string EchoString(string input);
}
public interface IInheritEcho : IEcho
{ }
public class EchoClass : IInheritEcho
{
public string EchoString(string input)
{
return input;
}
}
[TestClass]
public class RuntimeBinderTest
{
[TestMethod]
public void RuntimeBinder_should_work_when_dynamic_parameters_are_passed_to_method_from_inherited_interface()
{
//Arrange
dynamic dynObject = new ExpandoObject();
dynObject.Foo = "Bar";
IInheritEcho echomore = new EchoClass();
string echo = null;
string exceptionMessage = null;
//Act
try
{
echo = echomore.EchoString(dynObject.Foo);
}
catch (RuntimeBinderException e)
{
exceptionMessage = e.Message;
}
//Assert
Assert.AreEqual(echo, dynObject.Foo, false, exceptionMessage);
}
[TestMethod]
public void RuntimeBinder_should_work_when_dynamic_parameters_are_passed_to_method_from_noninherited_interface()
{
//Arrange
dynamic dynObject = new ExpandoObject();
dynObject.Foo = "Bar";
IEcho echomore = new EchoClass();
string echo = null;
string exceptionMessage = null;
//Act
try
{
echo = echomore.EchoString(dynObject.Foo);
}
catch (RuntimeBinderException e)
{
exceptionMessage = e.Message;
}
//Assert
Assert.AreEqual(echo, dynObject.Foo, false, exceptionMessage);
}
}
}
Test # 1 non riesce: Assert.AreEqual riuscita. Previsto: < (null)>. Effettivo:. 'Test.Utility.IInheritEcho' non contiene una definizione per 'EchoString'
Test # 2 Riesce.
La mia domanda è se la mia ipotesi che il primo test debba passare è corretta o c'è una ragione fondamentale nel quadro che non lo è?
So che posso risolvere il problema colando i parametri quando li passo o li assegno alle variabili prima di passarle. Sono più curioso sul motivo per cui l'interfaccia ereditata sta causando il fallimento di RuntimeBinder. ..
Hai perfettamente ragione. (Sebbene sia di una versione precedente di C#: http://msdn.microsoft.com/en-us/library/aa664578%28VS.71%29.aspx) Deve esserci un errore. Cosa succede se si utilizza una classe regolare con una proprietà stringa anziché l'oggetto expando? Trova il metodo nell'interfaccia ereditata? (Non avere VS qui per fare il test da solo). Se era con il binding statico (binding in tempo di compilazione), allora c'è qualcosa di sbagliato con il raccoglitore dinamico (run time binder). – JotaBe
L'utilizzo di una classe regolare con una proprietà stringa passa come previsto. È sicuramente il legatore di runtime che non si comporta ... – piff
Se si guarda il link di risposta di igofed a Microsof Connect, questo bug è knwon e molto probabilmente non verrà risolto nella nuova versione di VS. – JotaBe