本文整理汇总了C#中System.Dynamic.DynamicMetaObject.NeedsDeferral方法的典型用法代码示例。如果您正苦于以下问题:C# DynamicMetaObject.NeedsDeferral方法的具体用法?C# DynamicMetaObject.NeedsDeferral怎么用?C# DynamicMetaObject.NeedsDeferral使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类System.Dynamic.DynamicMetaObject
的用法示例。
在下文中一共展示了DynamicMetaObject.NeedsDeferral方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: Call
internal static DynamicMetaObject Call(DynamicMetaObjectBinder call, DynamicMetaObject target, DynamicMetaObject[] args)
{
Assert.NotNull(call, args);
Assert.NotNullItems(args);
if (target.NeedsDeferral())
return call.Defer(ArrayUtils.Insert(target, args));
foreach (var mo in args)
{
if (mo.NeedsDeferral())
{
RestrictTypes(args);
return call.Defer(
ArrayUtils.Insert(target, args)
);
}
}
DynamicMetaObject self = target.Restrict(target.GetLimitType());
ValidationInfo valInfo = BindingHelpers.GetValidationInfo(target);
TotemType tt = DynamicHelpers.GetTotemType(target.Value);
TotemContext toContext = GetTotemContext(call);
throw new NotImplementedException();
}
示例2: FallbackWorker
internal static DynamicMetaObject FallbackWorker(DynamicMetaObject/*!*/ self, Expression/*!*/ codeContext, string name, GetMemberOptions options, DynamicMetaObjectBinder action) {
if (self.NeedsDeferral()) {
return action.Defer(self);
}
bool isNoThrow = ((options & GetMemberOptions.IsNoThrow) != 0) ? true : false;
Type limitType = self.GetLimitType() ;
if (limitType == typeof(DynamicNull) || PythonBinder.IsPythonType(limitType)) {
// look up in the PythonType so that we can
// get our custom method names (e.g. string.startswith)
PythonType argType = DynamicHelpers.GetPythonTypeFromType(limitType);
// if the name is defined in the CLS context but not the normal context then
// we will hide it.
if (argType.IsHiddenMember(name)) {
DynamicMetaObject baseRes = BinderState.GetBinderState(action).Binder.GetMember(
name,
self,
codeContext,
isNoThrow
);
Expression failure = GetFailureExpression(limitType, name, isNoThrow, action);
return BindingHelpers.FilterShowCls(codeContext, action, baseRes, failure);
}
}
if (self.GetLimitType() == typeof(OldInstance)) {
if ((options & GetMemberOptions.IsNoThrow) != 0) {
return new DynamicMetaObject(
Ast.Field(
null,
typeof(OperationFailed).GetField("Value")
),
self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, typeof(OldInstance)))
);
} else {
return new DynamicMetaObject(
Ast.Throw(
Ast.Call(
typeof(PythonOps).GetMethod("AttributeError"),
Ast.Constant("{0} instance has no attribute '{1}'"),
Ast.NewArrayInit(
typeof(object),
Ast.Constant(((OldInstance)self.Value)._class._name),
Ast.Constant(name)
)
)
),
self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, typeof(OldInstance)))
);
}
}
var res = BinderState.GetBinderState(action).Binder.GetMember(name, self, codeContext, isNoThrow);
// Default binder can return something typed to boolean or int.
// If that happens, we need to apply Python's boxing rules.
if (res.Expression.Type == typeof(bool) || res.Expression.Type == typeof(int)) {
res = new DynamicMetaObject(
AstUtils.Convert(res.Expression, typeof(object)),
res.Restrictions
);
}
return res;
}
示例3: Call
internal static DynamicMetaObject Call(DynamicMetaObjectBinder/*!*/ call, DynamicMetaObject target, DynamicMetaObject/*!*/[]/*!*/ args) {
Assert.NotNull(call, args);
Assert.NotNullItems(args);
if (target.NeedsDeferral()) {
return call.Defer(ArrayUtils.Insert(target, args));
}
foreach (DynamicMetaObject mo in args) {
if (mo.NeedsDeferral()) {
RestrictTypes(args);
return call.Defer(
ArrayUtils.Insert(target, args)
);
}
}
DynamicMetaObject self = target.Restrict(target.GetLimitType());
ValidationInfo valInfo = BindingHelpers.GetValidationInfo(target);
PythonType pt = DynamicHelpers.GetPythonType(target.Value);
BinderState state = BinderState.GetBinderState(call);
// look for __call__, if it's present dispatch to it. Otherwise fall back to the
// default binder
PythonTypeSlot callSlot;
if (!typeof(Delegate).IsAssignableFrom(target.GetLimitType()) &&
pt.TryResolveSlot(state.Context, Symbols.Call, out callSlot)) {
ConditionalBuilder cb = new ConditionalBuilder(call);
Expression body;
callSlot.MakeGetExpression(
state.Binder,
BinderState.GetCodeContext(call),
self.Expression,
GetPythonType(self),
cb
);
if (!cb.IsFinal) {
cb.FinishCondition(GetCallError(self));
}
Expression[] callArgs = ArrayUtils.Insert(
BinderState.GetCodeContext(call),
cb.GetMetaObject().Expression,
DynamicUtils.GetExpressions(args)
);
body = Ast.Dynamic(
BinderState.GetBinderState(call).Invoke(
BindingHelpers.GetCallSignature(call)
),
typeof(object),
callArgs
);
return BindingHelpers.AddDynamicTestAndDefer(
call,
new DynamicMetaObject(body, self.Restrictions.Merge(BindingRestrictions.Combine(args))),
args,
valInfo
);
}
return null;
}
示例4: GenericInvokeMember
/// <summary>
/// Transforms an invoke member into a Python GetMember/Invoke. The caller should
/// verify that the given attribute is not resolved against a normal .NET class
/// before calling this. If it is a normal .NET member then a fallback InvokeMember
/// is preferred.
/// </summary>
internal static DynamicMetaObject/*!*/ GenericInvokeMember(InvokeMemberBinder/*!*/ action, ValidationInfo valInfo, DynamicMetaObject target, DynamicMetaObject/*!*/[]/*!*/ args) {
if (target.NeedsDeferral()) {
return action.Defer(args);
}
return AddDynamicTestAndDefer(action,
action.FallbackInvoke(
new DynamicMetaObject(
Binders.Get(
PythonContext.GetCodeContext(action),
PythonContext.GetPythonContext(action),
typeof(object),
action.Name,
target.Expression
),
BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target)
),
args,
null
),
args,
valInfo
);
}
示例5: FallbackConvert
public override DynamicMetaObject FallbackConvert(DynamicMetaObject self, DynamicMetaObject onBindingError) {
if (self.NeedsDeferral()) {
return Defer(self);
}
Type type = Type;
DynamicMetaObject res = null;
switch (Type.GetTypeCode(type)) {
case TypeCode.Boolean:
res = MakeToBoolConversion(self);
break;
case TypeCode.Char:
res = TryToCharConversion(self);
break;
case TypeCode.Object:
// !!! Deferral?
if (type.IsArray && self.Value is PythonTuple && type.GetArrayRank() == 1) {
res = MakeToArrayConversion(self, type);
} else if (type.IsGenericType && !type.IsAssignableFrom(CompilerHelpers.GetType(self.Value))) {
Type genTo = type.GetGenericTypeDefinition();
// Interface conversion helpers...
if (genTo == typeof(IList<>)) {
res = TryToGenericInterfaceConversion(self, type, typeof(IList<object>), typeof(ListGenericWrapper<>));
} else if (genTo == typeof(IDictionary<,>)) {
res = TryToGenericInterfaceConversion(self, type, typeof(IDictionary<object, object>), typeof(DictionaryGenericWrapper<,>));
} else if (genTo == typeof(IEnumerable<>)) {
res = TryToGenericInterfaceConversion(self, type, typeof(IEnumerable), typeof(IEnumerableOfTWrapper<>));
}
} else if (type == typeof(IEnumerable)) {
if (self.GetLimitType() == typeof(string)) {
// replace strings normal enumeration with our own which returns strings instead of chars.
res = new DynamicMetaObject(
Ast.Call(
typeof(StringOps).GetMethod("ConvertToIEnumerable"),
AstUtils.Convert(self.Expression, typeof(string))
),
BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, typeof(string))
);
} else if (!typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) && IsIndexless(self)) {
res = PythonProtocol.ConvertToIEnumerable(this, self.Restrict(self.GetLimitType()));
}
} else if (type == typeof(IEnumerator) ) {
if (!typeof(IEnumerator).IsAssignableFrom(self.GetLimitType()) &&
!typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) &&
IsIndexless(self)) {
res = PythonProtocol.ConvertToIEnumerator(this, self.Restrict(self.GetLimitType()));
}
}
break;
}
if (type.IsEnum && Enum.GetUnderlyingType(type) == self.GetLimitType()) {
// numeric type to enum, this is ok if the value is zero
object value = Activator.CreateInstance(type);
return new DynamicMetaObject(
Ast.Condition(
Ast.Equal(
AstUtils.Convert(self.Expression, Enum.GetUnderlyingType(type)),
Ast.Constant(Activator.CreateInstance(self.GetLimitType()))
),
Ast.Constant(value),
Ast.Call(
typeof(PythonOps).GetMethod("TypeErrorForBadEnumConversion").MakeGenericMethod(type),
AstUtils.Convert(self.Expression, typeof(object))
)
),
self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, self.GetLimitType())),
value
);
}
return res ?? Binder.Binder.ConvertTo(Type, ResultKind, self);
}
示例6: MakeToBoolConversion
private DynamicMetaObject/*!*/ MakeToBoolConversion(DynamicMetaObject/*!*/ self) {
DynamicMetaObject res = null;
if (self.NeedsDeferral()) {
res = Defer(self);
} else {
if (self.HasValue) {
self = self.Restrict(self.GetRuntimeType());
}
// Optimization: if we already boxed it to a bool, and now
// we're unboxing it, remove the unnecessary box.
if (self.Expression.NodeType == ExpressionType.Convert && self.Expression.Type == typeof(object)) {
var convert = (UnaryExpression)self.Expression;
if (convert.Operand.Type == typeof(bool)) {
return new DynamicMetaObject(convert.Operand, self.Restrictions);
}
}
if (self.GetLimitType() == typeof(DynamicNull)) {
// None has no __nonzero__ and no __len__ but it's always false
res = MakeNoneToBoolConversion(self);
} else if (self.GetLimitType() == typeof(bool)) {
// nothing special to convert from bool to bool
res = self;
} else if (typeof(IStrongBox).IsAssignableFrom(self.GetLimitType())) {
// Explictly block conversion of References to bool
res = MakeStrongBoxToBoolConversionError(self);
} else if (self.GetLimitType().IsPrimitive || self.GetLimitType().IsEnum) {
// optimization - rather than doing a method call for primitives and enums generate
// the comparison to zero directly.
res = MakePrimitiveToBoolComparison(self);
} else {
// anything non-null that doesn't fall under one of the above rules is true. So we
// fallback to the base Python conversion which will check for __nonzero__ and
// __len__. The fallback is handled by our ConvertTo site binder.
return
PythonProtocol.ConvertToBool(this, self) ??
new DynamicMetaObject(
Ast.Constant(true),
self.Restrictions
);
}
}
return res;
}