internal bool TryGetMemberValue(Type type, object obj, string name, out JsValue value) { object result; // dictionaries. if (typeof(IDictionary).IsAssignableFrom(type)) { IDictionary dictionary = (IDictionary)obj; if (dictionary.Contains(name)) { result = dictionary[name]; value = _convert.ToJsValue(result); } else { value = JsValue.Null; } return true; } BindingFlags flags; if (type == obj) { flags = BindingFlags.Public | BindingFlags.Static; } else { flags = BindingFlags.Public | BindingFlags.Instance; } // First of all try with a public property (the most common case). PropertyInfo pi = type.GetProperty(name, flags); if (pi != null) { result = pi.GetValue(obj, null); value = _convert.ToJsValue(result); return true; } // try field. FieldInfo fi = type.GetField(name, flags); if (fi != null) { result = fi.GetValue(obj); value = _convert.ToJsValue(result); return true; } // Then with an instance method: the problem is that we don't have a list of // parameter types so we just check if any method with the given name exists // and then keep alive a "weak delegate", i.e., just a name and the target. // The real method will be resolved during the invokation itself. BindingFlags mFlags = flags | BindingFlags.FlattenHierarchy; // TODO: This is probably slooow. if (type.GetMethods(mFlags).Any(x => x.Name == name)) { if (type == obj) { result = new WeakDelegate(type, name); } else { result = new WeakDelegate(obj, name); } value = _convert.ToJsValue(result); return true; } value = JsValue.Null; return false; }