提交 5d2517ba 编写于 作者: V Vladimir Sadov 提交者: GitHub

Merge pull request dotnet/corefx#13969 from bartdesmet/DynamicObjectIsOverridden

Optimize IsOverridden logic in DynamicObject

Commit migrated from https://github.com/dotnet/corefx/commit/49d22cabf3e34adb041d4c8e629b5c953afd67f9
......@@ -227,10 +227,10 @@ internal MetaDynamic(Expression expression, DynamicObject value)
public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
{
if (IsOverridden(nameof(DynamicObject.TryGetMember)))
if (IsOverridden(DynamicObject_TryGetMember))
{
return CallMethodWithResult(
nameof(DynamicObject.TryGetMember),
DynamicObject_TryGetMember,
binder,
s_noArgs,
(MetaDynamic @this, GetMemberBinder b, DynamicMetaObject e) => b.FallbackGetMember(@this, e)
......@@ -242,12 +242,12 @@ public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
{
if (IsOverridden(nameof(DynamicObject.TrySetMember)))
if (IsOverridden(DynamicObject_TrySetMember))
{
DynamicMetaObject localValue = value;
return CallMethodReturnLast(
nameof(DynamicObject.TrySetMember),
DynamicObject_TrySetMember,
binder,
s_noArgs,
value.Expression,
......@@ -260,10 +260,10 @@ public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicM
public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder)
{
if (IsOverridden(nameof(DynamicObject.TryDeleteMember)))
if (IsOverridden(DynamicObject_TryDeleteMember))
{
return CallMethodNoResult(
nameof(DynamicObject.TryDeleteMember),
DynamicObject_TryDeleteMember,
binder,
s_noArgs,
(MetaDynamic @this, DeleteMemberBinder b, DynamicMetaObject e) => b.FallbackDeleteMember(@this, e)
......@@ -275,10 +275,10 @@ public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder)
public override DynamicMetaObject BindConvert(ConvertBinder binder)
{
if (IsOverridden(nameof(DynamicObject.TryConvert)))
if (IsOverridden(DynamicObject_TryConvert))
{
return CallMethodWithResult(
nameof(DynamicObject.TryConvert),
DynamicObject_TryConvert,
binder,
s_noArgs,
(MetaDynamic @this, ConvertBinder b, DynamicMetaObject e) => b.FallbackConvert(@this, e)
......@@ -306,11 +306,11 @@ public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, Dy
// tree or doing .NET binding.
//
DynamicMetaObject call = BuildCallMethodWithResult(
nameof(DynamicObject.TryInvokeMember),
DynamicObject_TryInvokeMember,
binder,
GetExpressions(args),
BuildCallMethodWithResult<GetMemberBinder>(
nameof(DynamicObject.TryGetMember),
DynamicObject_TryGetMember,
new GetBinderAdapter(binder),
s_noArgs,
binder.FallbackInvokeMember(this, args, null),
......@@ -324,12 +324,12 @@ public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, Dy
public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder, DynamicMetaObject[] args)
{
if (IsOverridden(nameof(DynamicObject.TryCreateInstance)))
if (IsOverridden(DynamicObject_TryCreateInstance))
{
DynamicMetaObject[] localArgs = args;
return CallMethodWithResult(
nameof(DynamicObject.TryCreateInstance),
DynamicObject_TryCreateInstance,
binder,
GetExpressions(args),
(MetaDynamic @this, CreateInstanceBinder b, DynamicMetaObject e) => b.FallbackCreateInstance(@this, localArgs, e)
......@@ -341,12 +341,12 @@ public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder
public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args)
{
if (IsOverridden(nameof(DynamicObject.TryInvoke)))
if (IsOverridden(DynamicObject_TryInvoke))
{
DynamicMetaObject[] localArgs = args;
return CallMethodWithResult(
nameof(DynamicObject.TryInvoke),
DynamicObject_TryInvoke,
binder,
GetExpressions(args),
(MetaDynamic @this, InvokeBinder b, DynamicMetaObject e) => b.FallbackInvoke(@this, localArgs, e)
......@@ -358,12 +358,12 @@ public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObj
public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
{
if (IsOverridden(nameof(DynamicObject.TryBinaryOperation)))
if (IsOverridden(DynamicObject_TryBinaryOperation))
{
DynamicMetaObject localArg = arg;
return CallMethodWithResult(
nameof(DynamicObject.TryBinaryOperation),
DynamicObject_TryBinaryOperation,
binder,
new[] { arg.Expression },
(MetaDynamic @this, BinaryOperationBinder b, DynamicMetaObject e) => b.FallbackBinaryOperation(@this, localArg, e)
......@@ -375,10 +375,10 @@ public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder bind
public override DynamicMetaObject BindUnaryOperation(UnaryOperationBinder binder)
{
if (IsOverridden(nameof(DynamicObject.TryUnaryOperation)))
if (IsOverridden(DynamicObject_TryUnaryOperation))
{
return CallMethodWithResult(
nameof(DynamicObject.TryUnaryOperation),
DynamicObject_TryUnaryOperation,
binder,
s_noArgs,
(MetaDynamic @this, UnaryOperationBinder b, DynamicMetaObject e) => b.FallbackUnaryOperation(@this, e)
......@@ -390,12 +390,12 @@ public override DynamicMetaObject BindUnaryOperation(UnaryOperationBinder binder
public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
{
if (IsOverridden(nameof(DynamicObject.TryGetIndex)))
if (IsOverridden(DynamicObject_TryGetIndex))
{
DynamicMetaObject[] localIndexes = indexes;
return CallMethodWithResult(
nameof(DynamicObject.TryGetIndex),
DynamicObject_TryGetIndex,
binder,
GetExpressions(indexes),
(MetaDynamic @this, GetIndexBinder b, DynamicMetaObject e) => b.FallbackGetIndex(@this, localIndexes, e)
......@@ -407,13 +407,13 @@ public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMet
public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
{
if (IsOverridden(nameof(DynamicObject.TrySetIndex)))
if (IsOverridden(DynamicObject_TrySetIndex))
{
DynamicMetaObject[] localIndexes = indexes;
DynamicMetaObject localValue = value;
return CallMethodReturnLast(
nameof(DynamicObject.TrySetIndex),
DynamicObject_TrySetIndex,
binder,
GetExpressions(indexes),
value.Expression,
......@@ -426,12 +426,12 @@ public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMet
public override DynamicMetaObject BindDeleteIndex(DeleteIndexBinder binder, DynamicMetaObject[] indexes)
{
if (IsOverridden(nameof(DynamicObject.TryDeleteIndex)))
if (IsOverridden(DynamicObject_TryDeleteIndex))
{
DynamicMetaObject[] localIndexes = indexes;
return CallMethodNoResult(
nameof(DynamicObject.TryDeleteIndex),
DynamicObject_TryDeleteIndex,
binder,
GetExpressions(indexes),
(MetaDynamic @this, DeleteIndexBinder b, DynamicMetaObject e) => b.FallbackDeleteIndex(@this, localIndexes, e)
......@@ -520,17 +520,17 @@ private static ConstantExpression Constant<TBinder>(TBinder binder)
/// Helper method for generating a MetaObject which calls a
/// specific method on Dynamic that returns a result
/// </summary>
private DynamicMetaObject CallMethodWithResult<TBinder>(string methodName, TBinder binder, Expression[] args, Fallback<TBinder> fallback)
private DynamicMetaObject CallMethodWithResult<TBinder>(MethodInfo method, TBinder binder, Expression[] args, Fallback<TBinder> fallback)
where TBinder : DynamicMetaObjectBinder
{
return CallMethodWithResult(methodName, binder, args, fallback, null);
return CallMethodWithResult(method, binder, args, fallback, null);
}
/// <summary>
/// Helper method for generating a MetaObject which calls a
/// specific method on Dynamic that returns a result
/// </summary>
private DynamicMetaObject CallMethodWithResult<TBinder>(string methodName, TBinder binder, Expression[] args, Fallback<TBinder> fallback, Fallback<TBinder> fallbackInvoke)
private DynamicMetaObject CallMethodWithResult<TBinder>(MethodInfo method, TBinder binder, Expression[] args, Fallback<TBinder> fallback, Fallback<TBinder> fallbackInvoke)
where TBinder : DynamicMetaObjectBinder
{
//
......@@ -539,7 +539,7 @@ private DynamicMetaObject CallMethodWithResult<TBinder>(string methodName, TBind
//
DynamicMetaObject fallbackResult = fallback(this, binder, null);
DynamicMetaObject callDynamic = BuildCallMethodWithResult(methodName, binder, args, fallbackResult, fallbackInvoke);
DynamicMetaObject callDynamic = BuildCallMethodWithResult(method, binder, args, fallbackResult, fallbackInvoke);
//
// Now, call fallback again using our new MO as the error
......@@ -560,10 +560,10 @@ private DynamicMetaObject CallMethodWithResult<TBinder>(string methodName, TBind
/// to the method as an object[] or NoArgs to signify that
/// the target method takes no parameters.
/// </summary>
private DynamicMetaObject BuildCallMethodWithResult<TBinder>(string methodName, TBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback<TBinder> fallbackInvoke)
private DynamicMetaObject BuildCallMethodWithResult<TBinder>(MethodInfo method, TBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback<TBinder> fallbackInvoke)
where TBinder : DynamicMetaObjectBinder
{
if (!IsOverridden(methodName))
if (!IsOverridden(method))
{
return fallbackResult;
}
......@@ -576,7 +576,7 @@ private DynamicMetaObject BuildCallMethodWithResult<TBinder>(string methodName,
// }
//
ParameterExpression result = Expression.Parameter(typeof(object), null);
ParameterExpression callArgs = methodName != nameof(DynamicObject.TryBinaryOperation) ? Expression.Parameter(typeof(object[]), null) : Expression.Parameter(typeof(object), null);
ParameterExpression callArgs = method != DynamicObject_TryBinaryOperation ? Expression.Parameter(typeof(object[]), null) : Expression.Parameter(typeof(object), null);
ReadOnlyCollection<Expression> callArgsValue = GetConvertedArgs(args);
var resultMO = new DynamicMetaObject(result, BindingRestrictions.Empty);
......@@ -655,11 +655,11 @@ private DynamicMetaObject BuildCallMethodWithResult<TBinder>(string methodName,
Expression.Block(
new TrueReadOnlyCollection<ParameterExpression>(result, callArgs),
new TrueReadOnlyCollection<Expression>(
methodName != nameof(DynamicObject.TryBinaryOperation) ? Expression.Assign(callArgs, Expression.NewArrayInit(typeof(object), callArgsValue)) : Expression.Assign(callArgs, callArgsValue[0]),
method != DynamicObject_TryBinaryOperation ? Expression.Assign(callArgs, Expression.NewArrayInit(typeof(object), callArgsValue)) : Expression.Assign(callArgs, callArgsValue[0]),
Expression.Condition(
Expression.Call(
GetLimitedSelf(),
typeof(DynamicObject).GetMethod(methodName),
method,
BuildCallArgs(
binder,
args,
......@@ -668,7 +668,7 @@ private DynamicMetaObject BuildCallMethodWithResult<TBinder>(string methodName,
)
),
Expression.Block(
methodName != nameof(DynamicObject.TryBinaryOperation) ? ReferenceArgAssign(callArgs, args) : AstUtils.Empty,
method != DynamicObject_TryBinaryOperation ? ReferenceArgAssign(callArgs, args) : AstUtils.Empty,
resultMO.Expression
),
fallbackResult.Expression,
......@@ -690,7 +690,7 @@ private DynamicMetaObject BuildCallMethodWithResult<TBinder>(string methodName,
/// to the method as an object[] or NoArgs to signify that
/// the target method takes no parameters.
/// </summary>
private DynamicMetaObject CallMethodReturnLast<TBinder>(string methodName, TBinder binder, Expression[] args, Expression value, Fallback<TBinder> fallback)
private DynamicMetaObject CallMethodReturnLast<TBinder>(MethodInfo method, TBinder binder, Expression[] args, Expression value, Fallback<TBinder> fallback)
where TBinder : DynamicMetaObjectBinder
{
//
......@@ -719,7 +719,7 @@ private DynamicMetaObject CallMethodReturnLast<TBinder>(string methodName, TBind
Expression.Condition(
Expression.Call(
GetLimitedSelf(),
typeof(DynamicObject).GetMethod(methodName),
method,
BuildCallArgs(
binder,
args,
......@@ -759,7 +759,7 @@ private DynamicMetaObject CallMethodReturnLast<TBinder>(string methodName, TBind
/// to the method as an object[] or NoArgs to signify that
/// the target method takes no parameters.
/// </summary>
private DynamicMetaObject CallMethodNoResult<TBinder>(string methodName, TBinder binder, Expression[] args, Fallback<TBinder> fallback)
private DynamicMetaObject CallMethodNoResult<TBinder>(MethodInfo method, TBinder binder, Expression[] args, Fallback<TBinder> fallback)
where TBinder : DynamicMetaObjectBinder
{
//
......@@ -782,7 +782,7 @@ private DynamicMetaObject CallMethodNoResult<TBinder>(string methodName, TBinder
Expression.Condition(
Expression.Call(
GetLimitedSelf(),
typeof(DynamicObject).GetMethod(methodName),
method,
BuildCallArgs(
binder,
args,
......@@ -818,13 +818,13 @@ private DynamicMetaObject CallMethodNoResult<TBinder>(string methodName, TBinder
/// implementation for the method provided then Dynamic falls back to the base class
/// behavior which lets the call site determine how the binder is performed.
/// </summary>
private bool IsOverridden(string method)
private bool IsOverridden(MethodInfo method)
{
MemberInfo[] methods = Value.GetType().GetMember(method, MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance);
MemberInfo[] methods = Value.GetType().GetMember(method.Name, MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance);
foreach (MethodInfo mi in methods)
{
if (mi.DeclaringType != typeof(DynamicObject) && mi.GetBaseDefinition().DeclaringType == typeof(DynamicObject))
if (mi.DeclaringType != typeof(DynamicObject) && mi.GetBaseDefinition() == method)
{
return true;
}
......
......@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Dynamic;
using System.Reflection;
using System.Runtime.CompilerServices;
......@@ -73,5 +74,65 @@ internal static partial class CachedReflectionInfo
public static MethodInfo CallSiteOps_Bind =>
s_CallSiteOps_Bind ??
(s_CallSiteOps_Bind = typeof(CallSiteOps).GetMethod(nameof(CallSiteOps.Bind)));
private static MethodInfo s_DynamicObject_TryGetMember;
public static MethodInfo DynamicObject_TryGetMember =>
s_DynamicObject_TryGetMember ??
(s_DynamicObject_TryGetMember = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TryGetMember)));
private static MethodInfo s_DynamicObject_TrySetMember;
public static MethodInfo DynamicObject_TrySetMember =>
s_DynamicObject_TrySetMember ??
(s_DynamicObject_TrySetMember = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TrySetMember)));
private static MethodInfo s_DynamicObject_TryDeleteMember;
public static MethodInfo DynamicObject_TryDeleteMember =>
s_DynamicObject_TryDeleteMember ??
(s_DynamicObject_TryDeleteMember = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TryDeleteMember)));
private static MethodInfo s_DynamicObject_TryGetIndex;
public static MethodInfo DynamicObject_TryGetIndex =>
s_DynamicObject_TryGetIndex ??
(s_DynamicObject_TryGetIndex = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TryGetIndex)));
private static MethodInfo s_DynamicObject_TrySetIndex;
public static MethodInfo DynamicObject_TrySetIndex =>
s_DynamicObject_TrySetIndex ??
(s_DynamicObject_TrySetIndex = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TrySetIndex)));
private static MethodInfo s_DynamicObject_TryDeleteIndex;
public static MethodInfo DynamicObject_TryDeleteIndex =>
s_DynamicObject_TryDeleteIndex ??
(s_DynamicObject_TryDeleteIndex = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TryDeleteIndex)));
private static MethodInfo s_DynamicObject_TryConvert;
public static MethodInfo DynamicObject_TryConvert =>
s_DynamicObject_TryConvert ??
(s_DynamicObject_TryConvert = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TryConvert)));
private static MethodInfo s_DynamicObject_TryInvoke;
public static MethodInfo DynamicObject_TryInvoke =>
s_DynamicObject_TryInvoke ??
(s_DynamicObject_TryInvoke = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TryInvoke)));
private static MethodInfo s_DynamicObject_TryInvokeMember;
public static MethodInfo DynamicObject_TryInvokeMember =>
s_DynamicObject_TryInvokeMember ??
(s_DynamicObject_TryInvokeMember = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TryInvokeMember)));
private static MethodInfo s_DynamicObject_TryBinaryOperation;
public static MethodInfo DynamicObject_TryBinaryOperation =>
s_DynamicObject_TryBinaryOperation ??
(s_DynamicObject_TryBinaryOperation = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TryBinaryOperation)));
private static MethodInfo s_DynamicObject_TryUnaryOperation;
public static MethodInfo DynamicObject_TryUnaryOperation =>
s_DynamicObject_TryUnaryOperation ??
(s_DynamicObject_TryUnaryOperation = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TryUnaryOperation)));
private static MethodInfo s_DynamicObject_TryCreateInstance;
public static MethodInfo DynamicObject_TryCreateInstance =>
s_DynamicObject_TryCreateInstance ??
(s_DynamicObject_TryCreateInstance = typeof(DynamicObject).GetMethod(nameof(DynamicObject.TryCreateInstance)));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册