Nope. The dynamic object does not apply the type at compile time, but does not magically make your object extensible (unless it is an ExpandoObject ).
However, you can create some kind of wrapper or proxy using DynamicObject ... something like:
public class ExpandedObjectFromApi : DynamicObject { private Dictionary<string, object> _customProperties = new Dictionary<string, object>(); private object _currentObject; public ExpandedObjectFromApi(dynamic sealedObject) { _currentObject = sealedObject; } private PropertyInfo GetPropertyInfo(string propertyName) { return _currentObject.GetType().GetProperty(propertyName); } public override bool TryGetMember(GetMemberBinder binder, out object result) { var prop = GetPropertyInfo(binder.Name); if(prop != null) { result = prop.GetValue(_currentObject); return true; } result = _customProperties[binder.Name]; return true; } public override bool TrySetMember(SetMemberBinder binder, object value) { var prop = GetPropertyInfo(binder.Name); if(prop != null) { prop.SetValue(_currentObject, value); return true; } if(_customProperties.ContainsKey(binder.Name)) _customProperties[binder.Name] = value; else _customProperties.Add(binder.Name, value); return true; } }
And then you can use it like:
dynamic myExpandedObject = new ExpandedObjectFromApi(sealedObject);
This should return the original properties of the object, if found, or if there is no property of this name in the original object, it will add it as the "custom" property.
I made the code in the Qaru editor and probably made a lot of mistakes, it is not suitable for copy / paste, and it needs a ton of error checking (it is also necessary to implement fields and methods if the resulting object has them). Just wrote this to get the main idea.
You can also add a special property (for example, something like WrappedObject ) and write it to TryGetMember to return the original object.
source share