src
GreedyMetaDynamic.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Dynamic;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using static Uncapsulator.CachedReflectionInfo;
namespace Uncapsulator
{
partial clast GreedyDynamicObject
{
internal sealed clast TrueReadOnlyCollection : ReadOnlyCollection
{
public TrueReadOnlyCollection (params T[] list)
: base ((IList)list)
{
}
}
private sealed clast GreedyMetaDynamic : DynamicMetaObject
{
internal GreedyMetaDynamic (Expression expression, GreedyDynamicObject value)
: base (expression, BindingRestrictions.Empty, value)
{
}
public override IEnumerable GetDynamicMemberNames () => Value.GetDynamicMemberNames ();
public override DynamicMetaObject BindGetMember (GetMemberBinder binder)
{
if (IsOverridden (DynamicObject_TryGetMember))
{
return CallMethodWithResult (
DynamicObject_TryGetMember,
binder,
s_noArgs,
(GreedyMetaDynamic @this, GetMemberBinder b, DynamicMetaObject e) => b.FallbackGetMember (@this, e)
);
}
return base.BindGetMember (binder);
}
public override DynamicMetaObject BindSetMember (SetMemberBinder binder, DynamicMetaObject value)
{
if (IsOverridden (DynamicObject_TrySetMember))
{
DynamicMetaObject localValue = value;
return CallMethodReturnLast (
DynamicObject_TrySetMember,
binder,
s_noArgs,
value.Expression,
(GreedyMetaDynamic @this, SetMemberBinder b, DynamicMetaObject e) => b.FallbackSetMember (@this, localValue, e)
);
}
return base.BindSetMember (binder, value);
}
public override DynamicMetaObject BindDeleteMember (DeleteMemberBinder binder)
{
if (IsOverridden (DynamicObject_TryDeleteMember))
{
return CallMethodNoResult (
DynamicObject_TryDeleteMember,
binder,
s_noArgs,
(GreedyMetaDynamic @this, DeleteMemberBinder b, DynamicMetaObject e) => b.FallbackDeleteMember (@this, e)
);
}
return base.BindDeleteMember (binder);
}
public override DynamicMetaObject BindConvert (ConvertBinder binder)
{
if (IsOverridden (DynamicObject_TryConvert))
{
return CallMethodWithResult (
DynamicObject_TryConvert,
binder,
s_noArgs,
(GreedyMetaDynamic @this, ConvertBinder b, DynamicMetaObject e) => b.FallbackConvert (@this, e)
);
}
return base.BindConvert (binder);
}
public override DynamicMetaObject BindInvokeMember (InvokeMemberBinder binder, DynamicMetaObject[] args)
{
// Generate a tree like:
//
// {
// object result;
// TryInvokeMember(payload, out result)
// ? result
// : TryGetMember(payload, out result)
// ? FallbackInvoke(result)
// : fallbackResult
// }
//
// Then it calls FallbackInvokeMember with this tree as the
// "error", giving the language the option of using this
// tree or doing .NET binding.
//
DynamicMetaObject call = BuildCallMethodWithResult (
DynamicObject_TryInvokeMember,
binder,
GetExpressions (args),
BuildCallMethodWithResult (
DynamicObject_TryGetMember,
new GetBinderAdapter (binder),
s_noArgs,
binder.FallbackInvokeMember (this, args, null),
(GreedyMetaDynamic @this, GetMemberBinder ignored, DynamicMetaObject e) => binder.FallbackInvoke (e, args, null)
),
null
);
// JJA - we should handle these methods, too, otherwise we can't wrap the result in another dynamic object.
if (binder.Name == "ToString" || binder.Name == "GetHashCode" || binder.Name == "GetType" || binder.Name == "Equals") return call;
return binder.FallbackInvokeMember (this, args, call);
}
public override DynamicMetaObject BindCreateInstance (CreateInstanceBinder binder, DynamicMetaObject[] args)
{
if (IsOverridden (DynamicObject_TryCreateInstance))
{
DynamicMetaObject[] localArgs = args;
return CallMethodWithResult (
DynamicObject_TryCreateInstance,
binder,
GetExpressions (args),
(GreedyMetaDynamic @this, CreateInstanceBinder b, DynamicMetaObject e) => b.FallbackCreateInstance (@this, localArgs, e)
);
}
return base.BindCreateInstance (binder, args);
}
public override DynamicMetaObject BindInvoke (InvokeBinder binder, DynamicMetaObject[] args)
{
if (IsOverridden (DynamicObject_TryInvoke))
{
DynamicMetaObject[] localArgs = args;
return CallMethodWithResult (
DynamicObject_TryInvoke,
binder,
GetExpressions (args),
(GreedyMetaDynamic @this, InvokeBinder b, DynamicMetaObject e) => b.FallbackInvoke (@this, localArgs, e)
);
}
return base.BindInvoke (binder, args);
}
public override DynamicMetaObject BindBinaryOperation (BinaryOperationBinder binder, DynamicMetaObject arg)
{
if (IsOverridden (DynamicObject_TryBinaryOperation))
{
DynamicMetaObject localArg = arg;
return CallMethodWithResult (
DynamicObject_TryBinaryOperation,
binder,
new[] { arg.Expression },
(GreedyMetaDynamic @this, BinaryOperationBinder b, DynamicMetaObject e) => b.FallbackBinaryOperation (@this, localArg, e)
);
}
return base.BindBinaryOperation (binder, arg);
}
public override DynamicMetaObject BindUnaryOperation (UnaryOperationBinder binder)
{
if (IsOverridden (DynamicObject_TryUnaryOperation))
{
return CallMethodWithResult (
DynamicObject_TryUnaryOperation,
binder,
s_noArgs,
(GreedyMetaDynamic @this, UnaryOperationBinder b, DynamicMetaObject e) => b.FallbackUnaryOperation (@this, e)
);
}
return base.BindUnaryOperation (binder);
}
public override DynamicMetaObject BindGetIndex (GetIndexBinder binder, DynamicMetaObject[] indexes)
{
if (IsOverridden (DynamicObject_TryGetIndex))
{
DynamicMetaObject[] localIndexes = indexes;
return CallMethodWithResult (
DynamicObject_TryGetIndex,
binder,
GetExpressions (indexes),
(GreedyMetaDynamic @this, GetIndexBinder b, DynamicMetaObject e) => b.FallbackGetIndex (@this, localIndexes, e)
);
}
return base.BindGetIndex (binder, indexes);
}
public override DynamicMetaObject BindSetIndex (SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
{
if (IsOverridden (DynamicObject_TrySetIndex))
{
DynamicMetaObject[] localIndexes = indexes;
DynamicMetaObject localValue = value;
return CallMethodReturnLast (
DynamicObject_TrySetIndex,
binder,
GetExpressions (indexes),
value.Expression,
(GreedyMetaDynamic @this, SetIndexBinder b, DynamicMetaObject e) => b.FallbackSetIndex (@this, localIndexes, localValue, e)
);
}
return base.BindSetIndex (binder, indexes, value);
}
public override DynamicMetaObject BindDeleteIndex (DeleteIndexBinder binder, DynamicMetaObject[] indexes)
{
if (IsOverridden (DynamicObject_TryDeleteIndex))
{
DynamicMetaObject[] localIndexes = indexes;
return CallMethodNoResult (
DynamicObject_TryDeleteIndex,
binder,
GetExpressions (indexes),
(GreedyMetaDynamic @this, DeleteIndexBinder b, DynamicMetaObject e) => b.FallbackDeleteIndex (@this, localIndexes, e)
);
}
return base.BindDeleteIndex (binder, indexes);
}
private delegate DynamicMetaObject Fallback (GreedyMetaDynamic @this, TBinder binder, DynamicMetaObject errorSuggestion);
#pragma warning disable CA1825 // used in reference comparison, requires unique object idensaty
private static readonly Expression[] s_noArgs = new Expression[0];
#pragma warning restore CA1825
private static ReadOnlyCollection GetConvertedArgs (params Expression[] args)
{
var paramArgs = new Expression[args.Length];
for (int i = 0; i < args.Length; i++)
{
paramArgs[i] = Expression.Convert (args[i], typeof (object));
}
return new TrueReadOnlyCollection (paramArgs);
}
///
/// Helper method for generating expressions that astign byRef call
/// parameters back to their original variables.
///
private static Expression ReferenceArgastign (Expression callArgs, Expression[] args)
{
ReadOnlyCollectionBuilder block = null;
for (int i = 0; i < args.Length; i++)
{
ParameterExpression variable = args[i] as ParameterExpression;
if (variable.IsByRef)
{
if (block == null)
block = new ReadOnlyCollectionBuilder ();
block.Add (
Expression.astign (
variable,
Expression.Convert (
Expression.ArrayIndex (
callArgs,
AstUtils.Constant (i)
),
variable.Type
)
)
);
}
}
if (block != null)
return Expression.Block (block);
else
return AstUtils.Empty;
}
///
/// Helper method for generating arguments for calling methods
/// on GreedyDynamicObject. parameters is either a list of ParameterExpressions
/// to be pasted to the method as an object[], or NoArgs to signify that
/// the target method takes no object[] parameter.
///
private static Expression[] BuildCallArgs (TBinder binder, /*JJA*/ bool isInvokeMember, Expression[] parameters, Expression arg0, Expression arg1)
where TBinder : DynamicMetaObjectBinder
{
// JJA
if (isInvokeMember)
return new Expression[] { Constant (binder), arg0, arg1, Expression.Constant (GetParameterModifiers (parameters)) };
if (!object.ReferenceEquals (parameters, s_noArgs))
return arg1 != null ? new Expression[] { Constant (binder), arg0, arg1 } : new Expression[] { Constant (binder), arg0 };
else
return arg1 != null ? new Expression[] { Constant (binder), arg1 } : new Expression[] { Constant (binder) };
}
private static ConstantExpression Constant (TBinder binder)
{
return Expression.Constant (binder, typeof (TBinder));
}
///
/// Helper method for generating a MetaObject which calls a
/// specific method on Dynamic that returns a result
///
private DynamicMetaObject CallMethodWithResult (MethodInfo method, TBinder binder, Expression[] args, Fallback fallback)
where TBinder : DynamicMetaObjectBinder
{
return CallMethodWithResult (method, binder, args, fallback, null);
}
///
/// Helper method for generating a MetaObject which calls a
/// specific method on Dynamic that returns a result
///
private DynamicMetaObject CallMethodWithResult (MethodInfo method, TBinder binder, Expression[] args, Fallback fallback, Fallback fallbackInvoke)
where TBinder : DynamicMetaObjectBinder
{
//
// First, call fallback to do default binding
// This produces either an error or a call to a .NET member
//
DynamicMetaObject fallbackResult = fallback (this, binder, null);
DynamicMetaObject callDynamic = BuildCallMethodWithResult (method, binder, args, fallbackResult, fallbackInvoke);
// JJA - to make TryConvert always work
if (method.Name == "TryConvert")
return callDynamic;
//
// Now, call fallback again using our new MO as the error
// When we do this, one of two things can happen:
// 1. Binding will succeed, and it will ignore our call to
// the dynamic method, OR
// 2. Binding will fail, and it will use the MO we created
// above.
//
return fallback (this, binder, callDynamic);
}
///
/// Helper method for generating a MetaObject which calls a
/// specific method on GreedyDynamicObject that returns a result.
///
/// args is either an array of arguments to be pasted
/// to the method as an object[] or NoArgs to signify that
/// the target method takes no parameters.
///
private DynamicMetaObject BuildCallMethodWithResult (MethodInfo method, TBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
where TBinder : DynamicMetaObjectBinder
{
if (!IsOverridden (method))
{
return fallbackResult;
}
//
// Build a new expression like:
// {
// object result;
// TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult
// }
//
ParameterExpression result = Expression.Parameter (typeof (object), null);
ParameterExpression callArgs = method != DynamicObject_TryBinaryOperation ? Expression.Parameter (typeof (object[]), null) : Expression.Parameter (typeof (object), null);
ReadOnlyCollection callArgsValue = GetConvertedArgs (args);
var resultMO = new DynamicMetaObject (result, BindingRestrictions.Empty);
// Need to add a conversion if calling TryConvert
if (binder.ReturnType != typeof (object))
{
Debug.astert (binder is ConvertBinder && fallbackInvoke == null);
UnaryExpression convert = Expression.Convert (resultMO.Expression, binder.ReturnType);
// will always be a cast or unbox
Debug.astert (convert.Method == null);
// Prepare a good exception message in case the convert will fail
// JJA - we don't have access to the Strings type:
//string convertFailed = System.Linq.Expressions.Strings.DynamicObjectResultNotastignable (
// "{0}",
// this.Value.GetType(),
// binder.GetType(),
// binder.ReturnType
//);
string convertFailed = $"Dynamic conversion failed: Could not convert type '{Value.WrappedType}' to '{binder.ReturnType}'.";
Expression condition;
// If the return type can not be astigned null then just check for type astignability otherwise allow null.
if (binder.ReturnType.IsValueType && Nullable.GetUnderlyingType (binder.ReturnType) == null)
{
condition = Expression.TypeIs (resultMO.Expression, binder.ReturnType);
}
else
{
condition = Expression.OrElse (
Expression.Equal (resultMO.Expression, AstUtils.Null),
Expression.TypeIs (resultMO.Expression, binder.ReturnType));
}
Expression checkedConvert = Expression.Condition (
condition,
convert,
Expression.Throw (
Expression.New (
InvalidCastException_Ctor_String,
new TrueReadOnlyCollection (
Expression.Call (
String_Format_String_ObjectArray,
Expression.Constant (convertFailed),
Expression.NewArrayInit (
typeof (object),
new TrueReadOnlyCollection (
Expression.Condition (
Expression.Equal (resultMO.Expression, AstUtils.Null),
Expression.Constant ("null"),
Expression.Call (
resultMO.Expression,
Object_GetType
),
typeof (object)
)
)
)
)
)
),
binder.ReturnType
),
binder.ReturnType
);
resultMO = new DynamicMetaObject (checkedConvert, resultMO.Restrictions);
}
if (fallbackInvoke != null)
{
resultMO = fallbackInvoke (this, binder, resultMO);
}
var callDynamic = new DynamicMetaObject (
Expression.Block (
new TrueReadOnlyCollection (result, callArgs),
new TrueReadOnlyCollection (
method != DynamicObject_TryBinaryOperation ? Expression.astign (callArgs, Expression.NewArrayInit (typeof (object), callArgsValue)) : Expression.astign (callArgs, callArgsValue[0]),
Expression.Condition (
Expression.Call (
GetLimitedSelf (),
method,
BuildCallArgs (
binder,
method.Name == "TryInvokeMember", // JJA
args,
callArgs,
result
)
),
Expression.Block (
method != DynamicObject_TryBinaryOperation ? ReferenceArgastign (callArgs, args) : AstUtils.Empty,
resultMO.Expression
),
fallbackResult.Expression,
binder.ReturnType
)
)
),
GetRestrictions ().Merge (resultMO.Restrictions).Merge (fallbackResult.Restrictions)
);
return callDynamic;
}
///
/// Helper method for generating a MetaObject which calls a
/// specific method on Dynamic, but uses one of the arguments for
/// the result.
///
/// args is either an array of arguments to be pasted
/// to the method as an object[] or NoArgs to signify that
/// the target method takes no parameters.
///
private DynamicMetaObject CallMethodReturnLast (MethodInfo method, TBinder binder, Expression[] args, Expression value, Fallback fallback)
where TBinder : DynamicMetaObjectBinder
{
//
// First, call fallback to do default binding
// This produces either an error or a call to a .NET member
//
DynamicMetaObject fallbackResult = fallback (this, binder, null);
//
// Build a new expression like:
// {
// object result;
// TrySetMember(payload, result = value) ? result : fallbackResult
// }
//
ParameterExpression result = Expression.Parameter (typeof (object), null);
ParameterExpression callArgs = Expression.Parameter (typeof (object[]), null);
ReadOnlyCollection callArgsValue = GetConvertedArgs (args);
var callDynamic = new DynamicMetaObject (
Expression.Block (
new TrueReadOnlyCollection (result, callArgs),
new TrueReadOnlyCollection (
Expression.astign (callArgs, Expression.NewArrayInit (typeof (object), callArgsValue)),
Expression.Condition (
Expression.Call (
GetLimitedSelf (),
method,
BuildCallArgs (
binder,
method.Name == "TryInvokeMember", // JJA
args,
callArgs,
Expression.astign (result, Expression.Convert (value, typeof (object)))
)
),
Expression.Block (
ReferenceArgastign (callArgs, args),
result
),
fallbackResult.Expression,
typeof (object)
)
)
),
GetRestrictions ().Merge (fallbackResult.Restrictions)
);
//
// Now, call fallback again using our new MO as the error
// When we do this, one of two things can happen:
// 1. Binding will succeed, and it will ignore our call to
// the dynamic method, OR
// 2. Binding will fail, and it will use the MO we created
// above.
//
return fallback (this, binder, callDynamic);
}
///
/// Helper method for generating a MetaObject which calls a
/// specific method on Dynamic, but uses one of the arguments for
/// the result.
///
/// args is either an array of arguments to be pasted
/// to the method as an object[] or NoArgs to signify that
/// the target method takes no parameters.
///
private DynamicMetaObject CallMethodNoResult (MethodInfo method, TBinder binder, Expression[] args, Fallback fallback)
where TBinder : DynamicMetaObjectBinder
{
//
// First, call fallback to do default binding
// This produces either an error or a call to a .NET member
//
DynamicMetaObject fallbackResult = fallback (this, binder, null);
ParameterExpression callArgs = Expression.Parameter (typeof (object[]), null);
ReadOnlyCollection callArgsValue = GetConvertedArgs (args);
//
// Build a new expression like:
// if (TryDeleteMember(payload)) { } else { fallbackResult }
//
var callDynamic = new DynamicMetaObject (
Expression.Block (
new TrueReadOnlyCollection (callArgs),
new TrueReadOnlyCollection (
Expression.astign (callArgs, Expression.NewArrayInit (typeof (object), callArgsValue)),
Expression.Condition (
Expression.Call (
GetLimitedSelf (),
method,
BuildCallArgs (
binder,
method.Name == "TryInvokeMember", // JJA
args,
callArgs,
null
)
),
Expression.Block (
ReferenceArgastign (callArgs, args),
AstUtils.Empty
),
fallbackResult.Expression,
typeof (void)
)
)
),
GetRestrictions ().Merge (fallbackResult.Restrictions)
);
//
// Now, call fallback again using our new MO as the error
// When we do this, one of two things can happen:
// 1. Binding will succeed, and it will ignore our call to
// the dynamic method, OR
// 2. Binding will fail, and it will use the MO we created
// above.
//
return fallback (this, binder, callDynamic);
}
///
/// Checks if the derived type has overridden the specified method. If there is no
/// implementation for the method provided then Dynamic falls back to the base clast
/// behavior which lets the call site determine how the binder is performed.
///
private bool IsOverridden (MethodInfo method)
{
MemberInfo[] methods = Value.GetType ().GetMember (method.Name, MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance);
foreach (MethodInfo mi in methods)
{
if (mi.DeclaringType != typeof (GreedyDynamicObject) && mi.GetBaseDefinition () == method)
{
return true;
}
}
return false;
}
///
/// Returns a Restrictions object which includes our current restrictions merged
/// with a restriction limiting our type
///
private BindingRestrictions GetRestrictions ()
{
Debug.astert (Restrictions == BindingRestrictions.Empty, "We don't merge, restrictions are always empty");
// JJA - added method below which was private
return GetTypeRestriction (this);
}
static BindingRestrictions GetTypeRestriction (DynamicMetaObject obj)
{
if (obj.Value == null && obj.HasValue)
{
return BindingRestrictions.GetInstanceRestriction (obj.Expression, null);
}
return BindingRestrictions.GetTypeRestriction (obj.Expression, obj.LimitType);
}
///
/// Returns our Expression converted to GreedyDynamicObject
///
private Expression GetLimitedSelf ()
{
// Convert to GreedyDynamicObject rather than LimitType, because
// the limit type might be non-public.
if (TypeUtil.AreEquivalent (Expression.Type, typeof (GreedyDynamicObject)))
{
return Expression;
}
return Expression.Convert (Expression, typeof (GreedyDynamicObject));
}
private new GreedyDynamicObject Value => (GreedyDynamicObject)base.Value;
// It is okay to throw NotSupported from this binder. This object
// is only used by GreedyDynamicObject.GetMember--it is not expected to
// (and cannot) implement binding semantics. It is just so the DO
// can use the Name and IgnoreCase properties.
private sealed clast GetBinderAdapter : GetMemberBinder
{
internal GetBinderAdapter (InvokeMemberBinder binder)
: base (binder.Name, binder.IgnoreCase)
{
}
public override DynamicMetaObject FallbackGetMember (DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
throw new NotSupportedException ();
}
}
internal static Expression[] GetExpressions (DynamicMetaObject[] objects)
{
Expression[] array = new Expression[objects.Length];
for (int i = 0; i < objects.Length; i++)
{
DynamicMetaObject dynamicMetaObject = objects[i];
Expression expression = array[i] = dynamicMetaObject.Expression;
}
return array;
}
// JJA
internal static ParameterModifier GetParameterModifiers (Expression[] objects)
{
var mod = new ParameterModifier (Math.Max (1, objects.Length));
for (int i = 0; i < objects.Length; i++)
{
if (objects[i] is ParameterExpression pa && pa.IsByRef) mod[i] = true;
//DynamicMetaObject dynamicMetaObject = objects [i];
//if (dynamicMetaObject.Expression is ParameterExpression pa && pa.IsByRef) mod[i] = true;
}
return mod;
}
}
}
static clast AstUtils
{
internal static readonly object BoxedFalse = false;
internal static readonly object BoxedTrue = true;
internal static readonly object BoxedIntM1 = -1;
internal static readonly object BoxedInt0 = 0;
internal static readonly object BoxedInt1 = 1;
internal static readonly object BoxedInt2 = 2;
internal static readonly object BoxedInt3 = 3;
internal static readonly object BoxedDefaultSByte = (sbyte)0;
internal static readonly object BoxedDefaultChar = '\0';
internal static readonly object BoxedDefaultInt16 = (short)0;
internal static readonly object BoxedDefaultInt64 = 0L;
internal static readonly object BoxedDefaultByte = (byte)0;
internal static readonly object BoxedDefaultUInt16 = (ushort)0;
internal static readonly object BoxedDefaultUInt32 = 0u;
internal static readonly object BoxedDefaultUInt64 = 0uL;
internal static readonly object BoxedDefaultSingle = 0f;
internal static readonly object BoxedDefaultDouble = 0.0;
internal static readonly object BoxedDefaultDecimal = 0m;
internal static readonly object BoxedDefaultDateTime = default (DateTime);
private static readonly ConstantExpression s_true = Expression.Constant (BoxedTrue);
private static readonly ConstantExpression s_false = Expression.Constant (BoxedFalse);
private static readonly ConstantExpression s_m1 = Expression.Constant (BoxedIntM1);
private static readonly ConstantExpression s_0 = Expression.Constant (BoxedInt0);
private static readonly ConstantExpression s_1 = Expression.Constant (BoxedInt1);
private static readonly ConstantExpression s_2 = Expression.Constant (BoxedInt2);
private static readonly ConstantExpression s_3 = Expression.Constant (BoxedInt3);
internal static readonly DefaultExpression Empty = Expression.Empty ();
internal static readonly ConstantExpression Null = Expression.Constant (null);
internal static ConstantExpression Constant (bool value)
{
if (!value)
{
return s_false;
}
return s_true;
}
internal static ConstantExpression Constant (int value)
{
switch (value)
{
case -1:
return s_m1;
case 0:
return s_0;
case 1:
return s_1;
case 2:
return s_2;
case 3:
return s_3;
default:
return Expression.Constant (value);
}
}
}
internal static partial clast CachedReflectionInfo
{
private static MethodInfo s_String_Format_String_ObjectArray;
internal static MethodInfo String_Format_String_ObjectArray =>
s_String_Format_String_ObjectArray ??
(s_String_Format_String_ObjectArray = typeof (string).GetMethod (nameof (string.Format), new Type[] { typeof (string), typeof (object[]) }));
private static ConstructorInfo s_InvalidCastException_Ctor_String;
internal static ConstructorInfo InvalidCastException_Ctor_String =>
s_InvalidCastException_Ctor_String ??
(s_InvalidCastException_Ctor_String = typeof (InvalidCastException).GetConstructor (new Type[] { typeof (string) }));
private static MethodInfo s_DynamicObject_TryGetMember;
internal static MethodInfo DynamicObject_TryGetMember =>
s_DynamicObject_TryGetMember ??
(s_DynamicObject_TryGetMember = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TryGetMember)));
private static MethodInfo s_DynamicObject_TrySetMember;
internal static MethodInfo DynamicObject_TrySetMember =>
s_DynamicObject_TrySetMember ??
(s_DynamicObject_TrySetMember = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TrySetMember)));
private static MethodInfo s_DynamicObject_TryDeleteMember;
internal static MethodInfo DynamicObject_TryDeleteMember =>
s_DynamicObject_TryDeleteMember ??
(s_DynamicObject_TryDeleteMember = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TryDeleteMember)));
private static MethodInfo s_DynamicObject_TryGetIndex;
internal static MethodInfo DynamicObject_TryGetIndex =>
s_DynamicObject_TryGetIndex ??
(s_DynamicObject_TryGetIndex = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TryGetIndex)));
private static MethodInfo s_DynamicObject_TrySetIndex;
internal static MethodInfo DynamicObject_TrySetIndex =>
s_DynamicObject_TrySetIndex ??
(s_DynamicObject_TrySetIndex = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TrySetIndex)));
private static MethodInfo s_DynamicObject_TryDeleteIndex;
internal static MethodInfo DynamicObject_TryDeleteIndex =>
s_DynamicObject_TryDeleteIndex ??
(s_DynamicObject_TryDeleteIndex = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TryDeleteIndex)));
private static MethodInfo s_DynamicObject_TryConvert;
internal static MethodInfo DynamicObject_TryConvert =>
s_DynamicObject_TryConvert ??
(s_DynamicObject_TryConvert = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TryConvert)));
private static MethodInfo s_DynamicObject_TryInvoke;
internal static MethodInfo DynamicObject_TryInvoke =>
s_DynamicObject_TryInvoke ??
(s_DynamicObject_TryInvoke = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TryInvoke)));
private static MethodInfo s_DynamicObject_TryInvokeMember;
internal static MethodInfo DynamicObject_TryInvokeMember =>
s_DynamicObject_TryInvokeMember ??
(s_DynamicObject_TryInvokeMember = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TryInvokeMember)));
private static MethodInfo s_DynamicObject_TryBinaryOperation;
internal static MethodInfo DynamicObject_TryBinaryOperation =>
s_DynamicObject_TryBinaryOperation ??
(s_DynamicObject_TryBinaryOperation = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TryBinaryOperation)));
private static MethodInfo s_DynamicObject_TryUnaryOperation;
internal static MethodInfo DynamicObject_TryUnaryOperation =>
s_DynamicObject_TryUnaryOperation ??
(s_DynamicObject_TryUnaryOperation = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TryUnaryOperation)));
private static MethodInfo s_DynamicObject_TryCreateInstance;
internal static MethodInfo DynamicObject_TryCreateInstance =>
s_DynamicObject_TryCreateInstance ??
(s_DynamicObject_TryCreateInstance = typeof (GreedyDynamicObject).GetMethod (nameof (GreedyDynamicObject.TryCreateInstance)));
}
internal static partial clast CachedReflectionInfo
{
private static ConstructorInfo s_Nullable_Boolean_Ctor;
internal static ConstructorInfo Nullable_Boolean_Ctor
=> s_Nullable_Boolean_Ctor ?? (s_Nullable_Boolean_Ctor = typeof (bool?).GetConstructor (new[] { typeof (bool) }));
private static ConstructorInfo s_Decimal_Ctor_Int32;
internal static ConstructorInfo Decimal_Ctor_Int32 =>
s_Decimal_Ctor_Int32 ??
(s_Decimal_Ctor_Int32 = typeof (decimal).GetConstructor (new[] { typeof (int) }));
private static ConstructorInfo s_Decimal_Ctor_UInt32;
internal static ConstructorInfo Decimal_Ctor_UInt32 =>
s_Decimal_Ctor_UInt32 ??
(s_Decimal_Ctor_UInt32 = typeof (decimal).GetConstructor (new[] { typeof (uint) }));
private static ConstructorInfo s_Decimal_Ctor_Int64;
internal static ConstructorInfo Decimal_Ctor_Int64 =>
s_Decimal_Ctor_Int64 ??
(s_Decimal_Ctor_Int64 = typeof (decimal).GetConstructor (new[] { typeof (long) }));
private static ConstructorInfo s_Decimal_Ctor_UInt64;
internal static ConstructorInfo Decimal_Ctor_UInt64 =>
s_Decimal_Ctor_UInt64 ??
(s_Decimal_Ctor_UInt64 = typeof (decimal).GetConstructor (new[] { typeof (ulong) }));
private static ConstructorInfo s_Decimal_Ctor_Int32_Int32_Int32_Bool_Byte;
internal static ConstructorInfo Decimal_Ctor_Int32_Int32_Int32_Bool_Byte =>
s_Decimal_Ctor_Int32_Int32_Int32_Bool_Byte ??
(s_Decimal_Ctor_Int32_Int32_Int32_Bool_Byte = typeof (decimal).GetConstructor (new[] { typeof (int), typeof (int), typeof (int), typeof (bool), typeof (byte) }));
private static FieldInfo s_Decimal_One;
internal static FieldInfo Decimal_One
=> s_Decimal_One ?? (s_Decimal_One = typeof (decimal).GetField (nameof (decimal.One)));
private static FieldInfo s_Decimal_MinusOne;
internal static FieldInfo Decimal_MinusOne
=> s_Decimal_MinusOne ?? (s_Decimal_MinusOne = typeof (decimal).GetField (nameof (decimal.MinusOne)));
private static FieldInfo s_Decimal_MinValue;
internal static FieldInfo Decimal_MinValue
=> s_Decimal_MinValue ?? (s_Decimal_MinValue = typeof (decimal).GetField (nameof (decimal.MinValue)));
private static FieldInfo s_Decimal_MaxValue;
internal static FieldInfo Decimal_MaxValue
=> s_Decimal_MaxValue ?? (s_Decimal_MaxValue = typeof (decimal).GetField (nameof (decimal.MaxValue)));
private static FieldInfo s_Decimal_Zero;
internal static FieldInfo Decimal_Zero
=> s_Decimal_Zero ?? (s_Decimal_Zero = typeof (decimal).GetField (nameof (decimal.Zero)));
private static FieldInfo s_DateTime_MinValue;
internal static FieldInfo DateTime_MinValue
=> s_DateTime_MinValue ?? (s_DateTime_MinValue = typeof (DateTime).GetField (nameof (DateTime.MinValue)));
private static MethodInfo s_MethodBase_GetMethodFromHandle_RuntimeMethodHandle;
internal static MethodInfo MethodBase_GetMethodFromHandle_RuntimeMethodHandle =>
s_MethodBase_GetMethodFromHandle_RuntimeMethodHandle ??
(s_MethodBase_GetMethodFromHandle_RuntimeMethodHandle = typeof (MethodBase).GetMethod (nameof (MethodBase.GetMethodFromHandle), new[] { typeof (RuntimeMethodHandle) }));
private static MethodInfo s_MethodBase_GetMethodFromHandle_RuntimeMethodHandle_RuntimeTypeHandle;
internal static MethodInfo MethodBase_GetMethodFromHandle_RuntimeMethodHandle_RuntimeTypeHandle =>
s_MethodBase_GetMethodFromHandle_RuntimeMethodHandle_RuntimeTypeHandle ??
(s_MethodBase_GetMethodFromHandle_RuntimeMethodHandle_RuntimeTypeHandle = typeof (MethodBase).GetMethod (nameof (MethodBase.GetMethodFromHandle), new[] { typeof (RuntimeMethodHandle), typeof (RuntimeTypeHandle) }));
private static MethodInfo s_MethodInfo_CreateDelegate_Type_Object;
internal static MethodInfo MethodInfo_CreateDelegate_Type_Object =>
s_MethodInfo_CreateDelegate_Type_Object ??
(s_MethodInfo_CreateDelegate_Type_Object = typeof (MethodInfo).GetMethod (nameof (MethodInfo.CreateDelegate), new[] { typeof (Type), typeof (object) }));
private static MethodInfo s_String_op_Equality_String_String;
internal static MethodInfo String_op_Equality_String_String =>
s_String_op_Equality_String_String ??
(s_String_op_Equality_String_String = typeof (string).GetMethod ("op_Equality", new[] { typeof (string), typeof (string) }));
private static MethodInfo s_String_Equals_String_String;
internal static MethodInfo String_Equals_String_String =>
s_String_Equals_String_String ??
(s_String_Equals_String_String = typeof (string).GetMethod ("Equals", new[] { typeof (string), typeof (string) }));
private static MethodInfo s_DictionaryOfStringInt32_Add_String_Int32;
internal static MethodInfo DictionaryOfStringInt32_Add_String_Int32 =>
s_DictionaryOfStringInt32_Add_String_Int32 ??
(s_DictionaryOfStringInt32_Add_String_Int32 = typeof (Dictionary).GetMethod (nameof (Dictionary.Add), new[] { typeof (string), typeof (int) }));
private static ConstructorInfo s_DictionaryOfStringInt32_Ctor_Int32;
internal static ConstructorInfo DictionaryOfStringInt32_Ctor_Int32 =>
s_DictionaryOfStringInt32_Ctor_Int32 ??
(s_DictionaryOfStringInt32_Ctor_Int32 = typeof (Dictionary).GetConstructor (new[] { typeof (int) }));
private static MethodInfo s_Type_GetTypeFromHandle;
internal static MethodInfo Type_GetTypeFromHandle =>
s_Type_GetTypeFromHandle ??
(s_Type_GetTypeFromHandle = typeof (Type).GetMethod (nameof (Type.GetTypeFromHandle)));
private static MethodInfo s_Object_GetType;
internal static MethodInfo Object_GetType =>
s_Object_GetType ??
(s_Object_GetType = typeof (object).GetMethod (nameof (object.GetType)));
private static MethodInfo s_Decimal_op_Implicit_Byte;
internal static MethodInfo Decimal_op_Implicit_Byte =>
s_Decimal_op_Implicit_Byte ??
(s_Decimal_op_Implicit_Byte = typeof (decimal).GetMethod ("op_Implicit", new[] { typeof (byte) }));
private static MethodInfo s_Decimal_op_Implicit_SByte;
internal static MethodInfo Decimal_op_Implicit_SByte =>
s_Decimal_op_Implicit_SByte ??
(s_Decimal_op_Implicit_SByte = typeof (decimal).GetMethod ("op_Implicit", new[] { typeof (sbyte) }));
private static MethodInfo s_Decimal_op_Implicit_Int16;
internal static MethodInfo Decimal_op_Implicit_Int16 =>
s_Decimal_op_Implicit_Int16 ??
(s_Decimal_op_Implicit_Int16 = typeof (decimal).GetMethod ("op_Implicit", new[] { typeof (short) }));
private static MethodInfo s_Decimal_op_Implicit_UInt16;
internal static MethodInfo Decimal_op_Implicit_UInt16 =>
s_Decimal_op_Implicit_UInt16 ??
(s_Decimal_op_Implicit_UInt16 = typeof (decimal).GetMethod ("op_Implicit", new[] { typeof (ushort) }));
private static MethodInfo s_Decimal_op_Implicit_Int32;
internal static MethodInfo Decimal_op_Implicit_Int32 =>
s_Decimal_op_Implicit_Int32 ??
(s_Decimal_op_Implicit_Int32 = typeof (decimal).GetMethod ("op_Implicit", new[] { typeof (int) }));
private static MethodInfo s_Decimal_op_Implicit_UInt32;
internal static MethodInfo Decimal_op_Implicit_UInt32 =>
s_Decimal_op_Implicit_UInt32 ??
(s_Decimal_op_Implicit_UInt32 = typeof (decimal).GetMethod ("op_Implicit", new[] { typeof (uint) }));
private static MethodInfo s_Decimal_op_Implicit_Int64;
internal static MethodInfo Decimal_op_Implicit_Int64 =>
s_Decimal_op_Implicit_Int64 ??
(s_Decimal_op_Implicit_Int64 = typeof (decimal).GetMethod ("op_Implicit", new[] { typeof (long) }));
private static MethodInfo s_Decimal_op_Implicit_UInt64;
internal static MethodInfo Decimal_op_Implicit_UInt64 =>
s_Decimal_op_Implicit_UInt64 ??
(s_Decimal_op_Implicit_UInt64 = typeof (decimal).GetMethod ("op_Implicit", new[] { typeof (ulong) }));
private static MethodInfo s_Decimal_op_Implicit_Char;
internal static MethodInfo Decimal_op_Implicit_Char =>
s_Decimal_op_Implicit_Char ??
(s_Decimal_op_Implicit_Char = typeof (decimal).GetMethod ("op_Implicit", new[] { typeof (char) }));
private static MethodInfo s_Math_Pow_Double_Double;
internal static MethodInfo Math_Pow_Double_Double =>
s_Math_Pow_Double_Double ??
(s_Math_Pow_Double_Double = typeof (Math).GetMethod (nameof (Math.Pow), new[] { typeof (double), typeof (double) }));
}
}