Pourquoi Microsoft.CSharp.RuntimeBinder.RuntimeBinderException si la méthode invoquée est-il?

J'ai le code suivant qui crée un objet dynamique qui est affecté à la smtpClient variable.

public class TranferManager
{
    public void Tranfer(Account from, Account to, Money amount)
    {
        //Perform the required actions
        var smtpClient = New.SmtpClient();
        smtpClient.Send("[email protected]", "from.Email", "Tranfer", "?");
        //In the previous line I get a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
        //with the description = "'object' does not contain a definition for 'Send'"
    }
}

public static class New
{
    public static dynamic SmtpClient(params object[] parameters)
    {
        return typeof(SmtpClient).New(parameters);
    }
}

public static class CreationExtensions
{
    private static Dictionary<Type, Func<object, dynamic>> builders =
        new Dictionary<Type, Func<object, dynamic>>();

    public static dynamic New(this Type type, params object[] parameters)
    {
        if(builders.ContainsKey(type))
            return builders[type](parameters);

        return Activator.CreateInstance(type, parameters);
    }

    public static void RegisterBuilder(this Type type, Func<object, dynamic> builder)
    {
        builders.Add(type, builder);
    }
}

Pour le tester, je suis à l'aide de l'UT (ci-dessous):

    [TestMethod()]
    public void TranferTest()
    {
        typeof(SmtpClient).RegisterBuilder(p => 
            new
            {
                Send = new Action<string, string, string, string>(
                (from, to, subject, body) => { })
            }
        );

        var tm = new TranferManager();
        tm.Tranfer(new Account(), new Account(), new Money());
        //Assert
    }

Quand j', à l'aide de la immédiats windows, demander la smtpClient de type I get:

smtpClient.GetType()
{<>f__AnonymousType0`1[System.Action`4[System.String,System.String,System.String,System.String]]}

Et quand je demande pour ses membres-je obtenir:

smtpClient.GetType().GetMembers()
{System.Reflection.MemberInfo[7]}
    [0]: {System.Action`4[System.String,System.String,System.String,System.String] get_Send()}
    [1]: {System.String ToString()}
    [2]: {Boolean Equals(System.Object)}
    [3]: {Int32 GetHashCode()}
    [4]: {System.Type GetType()}
    [5]: {Void .ctor(System.Action`4[System.String,System.String,System.String,System.String])}
    [6]: {System.Action`4[System.String,System.String,System.String,System.String] Send}

Donc, ma question est: Pourquoi suis-je l'exception?

uhmm... copier le code dans une Application Console (et le contenu de votre méthode de test dans mon "main" de la méthode), il ne lève pas d'exception pour moi. Je suppose que votre TestMethod est dans une autre dll. Peut-être il y a un problème avec la .NET version que vous ciblez dans la dll ou de ses références?
Même chose ici. Lorsque j'exécute votre code (avoir fourni des définitions de Compte, l'Argent, etc), j'ai fait pas exception. Pouvez-vous fournir un petit programme qui en fait, compile, s'exécute, et illustre le problème?
Vous êtes en droit, copier le code de test dans un "Main()" méthode d'une application console, il fonctionne. Maintenant, je peux voir le problème: les annonymous type (créé dans le test de dll) n'est pas visible de son dll.

OriginalL'auteur lontivero | 2011-04-15