public class CustomMetaObject : DynamicMetaObject { public CustomMetaObject(Expression expression, object value) : base(expression, BindingRestrictions.Empty, value) { } public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args) { if (binder.Name == "DoSomething") { return base.BindInvokeMember(binder, args); } else { return new DynamicMetaObject( Expression.Constant(null), // return null for disallowed operations BindingRestrictions.GetTypeRestriction(Expression, LimitType), null); } } } // usage dynamic obj = new CustomMetaObject(Expression.Constant(null), new ExpandoObject()); obj.DoSomething(); // allowed obj.DoSomethingElse(); // disallowed
public class RuntimeRestrictMetaObject : DynamicMetaObject { public RuntimeRestrictMetaObject(Expression expression, object value) : base(expression, BindingRestrictions.Empty, value) { } public override DynamicMetaObject BindGetMember(GetMemberBinder binder) { if (IsAllowed(binder.Name)) { return base.BindGetMember(binder); } else { return new DynamicMetaObject( Expression.Constant(null), // return null for disallowed operations BindingRestrictions.GetTypeRestriction(Expression, LimitType), null); } } public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args) { if (IsAllowed(binder.Name)) { return base.BindInvokeMember(binder, args); } else { return new DynamicMetaObject( Expression.Constant(null), // return null for disallowed operations BindingRestrictions.GetTypeRestriction(Expression, LimitType), null); } } private bool IsAllowed(string operationName) { // example runtime condition: disallow operations on any members whose name starts with an underscore return !operationName.StartsWith("_"); } } // usage dynamic obj = new RuntimeRestrictMetaObject(Expression.Constant(null), new ExpandoObject()); var value = obj.NonRestrictedMember; // allowed string nonExistent = obj._DisallowedMember; // disallowed; returns nullThe examples above are not specific to any package library. The System.Dynamic namespace is included in the C# standard library, so the examples use that.