lontivero lontivero - 7 months ago 80
C# Question

Why a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException if the invoked method is there?

I have the following code which creates a dynamic object that is assigned to the smtpClient variable.

public class TranferManager
public void Tranfer(Account from, Account to, Money amount)
// Perform the required actions
var smtpClient = New.SmtpClient();
smtpClient.Send("info@bank.com", "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)
return builders[type](parameters);

return Activator.CreateInstance(type, parameters);

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

To test it I am using the UT (below):

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

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

When I, using the inmediate windows, ask for the smtpClient type I get:


And when I ask for its members I get:

[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}

So, my question is: Why am I getting that exception?


Anonymous types are internal, if you cross assembly boundaries dynamic can't resolve the property.

Rather than using an anonymous type, try using an actual type or an Expando Object.