none
TypeDescriptor.GetReflectionType(object instance)与object.GetType()? RRS feed

  • 问题

  • TypeDescriptor.GetReflectionType 介绍是:如果给定对象,则返回可用于执行反射的 System.Type。

    object.GetType 介绍是:获取当前实例的 System.Type。

    我在ControlCodeDomSerializer.cs源码中看到的使用,我原代码使用,但是发现一个问题,TypeDescriptor.GetReflectionType不起作用

    以下是关键代码:

    private void SerializeSuspendLayout(IDesignerSerializationManager manager, CodeStatementCollection codeStatements, object control)
    {
        SerializeMethodInvocation(manager, codeStatements, control, "SuspendLayout", null, new Type[0], StatementOrdering.Prepend);
    }
    
    private void SerializeResumeLayout(IDesignerSerializationManager manager, CodeStatementCollection codeStatements, object control)
    {
        CodeExpressionCollection parameters = new CodeExpressionCollection();
        parameters.Add(new CodePrimitiveExpression(false));
        Type[] paramTypes = new Type[]{ typeof(bool) };
        SerializeMethodInvocation(manager, codeStatements, control, "ResumeLayout", parameters, paramTypes, StatementOrdering.Append);
    }
    
    protected void SerializeMethodInvocation(IDesignerSerializationManager manager, CodeStatementCollection statements, object control, string methodName, CodeExpressionCollection parameters, Type[] paramTypes, StatementOrdering ordering)
    {
        using (TraceScopeInternal("MoniControlCodeDomSerializer::SerializeMethodInvocation(" + methodName + ")"))
        {
            string name = manager.GetName(control);
            TraceInternal(name + "." + methodName);
    
            // Use IReflect to see if this method name exists on the control. 
            // ↓ GetReflectionType doesn't seem to work !?
    
            //MethodInfo methodInfo = TypeDescriptor.GetReflectionType(control).GetMethod(methodName,
            //    BindingFlags.Public | BindingFlags.Instance, null, paramTypes, null);
            MethodInfo methodInfo = control.GetType().GetMethod(methodName,
                BindingFlags.Public | BindingFlags.Instance, null, paramTypes, null);
            if (methodInfo != null)
            {
                CodeExpression field = SerializeToExpression(manager, control);
                CodeMethodReferenceExpression method = new CodeMethodReferenceExpression(field, methodName);
                CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression();
                methodInvoke.Method = method;
                if (parameters != null)
                {
                    methodInvoke.Parameters.AddRange(parameters);
                }
    
                CodeExpressionStatement statement = new CodeExpressionStatement(methodInvoke);
                switch (ordering)
                {
                    case StatementOrdering.Prepend:
                        statement.UserData["statement-ordering"] = "begin";
                        break;
                    case StatementOrdering.Append:
                        statement.UserData["statement-ordering"] = "end";
                        break;
                    default:
                        Debug.Fail("Unsupported statement ordering: " + ordering);
                        break;
                }
    
                statements.Add(statement);
            }
        }
    }

    使用:TypeDescriptor.GetReflectionType

    SerializeSuspendLayout调用执行到MethodInfo,会获取到方法

    但是调用SerializeResumeLayout执行到MethodInfo,会获取不了

    ----------------------------------------------------

    使用object.GetType都会获取到,以下是对应类型的对应方法

    public void SuspendLayout()
    {
    	layoutSuspendCount++;
    }
    
    public void ResumeLayout(bool performLayout)
    {
        if (layoutSuspendCount > 0)
        {
            layoutSuspendCount--;
            if (layoutSuspendCount == 0 || performLayout)
            {
                PerformLayout();
            }
        }
    }

    不知道他们的具体有什么区别?

    2019年4月23日 4:24

答案


  • Hi   Troy_Zhang,

    根据目前的情况,并不清楚不起作用的原因,按照文档说明,是可以获取对应实列的元数据信息的。

    如果只是需要在运行时访问某类型的元数据的方式,建议使用System.Reflection 命名空间中提供的反射 API( Object 类的 GetType


    下面文章或许能帮助到你,你也可以查阅更多的资料。

    TypeDescriptor家族和Type家族大比拼:



    Best Regards

    Yong Lu

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 Troy_Zhang 2019年4月27日 9:08
    2019年4月25日 6:47
    版主

全部回复

  • Hi    Troy_Zhang,

    >> 使用:TypeDescriptor.GetReflectionType

    SerializeSuspendLayout调用执行到MethodInfo,会获取到方法

    但是调用SerializeResumeLayout执行到MethodInfo,会获取不了


    TypeDescriptor.GetReflectionType Method(): 通过给定一个对象或者类型,返回一个可以执行反射的类型。

    用法上没有什么区别。我根据你的代码做了个测试,是可以获取的。

          CodeExpressionCollection parameters = new CodeExpressionCollection();
                parameters.Add(new CodePrimitiveExpression(false));
                Type[] paramTypes = new Type[] { typeof(bool) };
    
                testcontrol control = new testcontrol();
                MethodInfo methodInfo = TypeDescriptor.GetReflectionType(control).GetMethod("ResumeLayout",
                    BindingFlags.Public | BindingFlags.Instance, null, paramTypes, null);
    
                if (methodInfo != null)
                {
                     
    
                }
    
        public class testcontrol
        {
            int layoutSuspendCount = 0;
    
            public void SuspendLayout()
            {
                layoutSuspendCount++;
            }
    
            public void ResumeLayout(bool performLayout)
            {
                if (layoutSuspendCount > 0)
                {
                    layoutSuspendCount--;
                    if (layoutSuspendCount == 0 || performLayout)
                    {
                        //PerformLayout();
                    }
                }
            }
        }
    

    Best Regards

    Yong Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2019年4月24日 7:14
    版主
  • 是的,在正常的代码中是没有错误的,但是如果你在CodeDomSerializer中使用,它的问题就出现了

    但是在ControlCodeDomSerializer.cs源码中,看起来不会出错,不知道是什么原因造成的

    2019年4月25日 4:34

  • Hi   Troy_Zhang,

    根据目前的情况,并不清楚不起作用的原因,按照文档说明,是可以获取对应实列的元数据信息的。

    如果只是需要在运行时访问某类型的元数据的方式,建议使用System.Reflection 命名空间中提供的反射 API( Object 类的 GetType


    下面文章或许能帮助到你,你也可以查阅更多的资料。

    TypeDescriptor家族和Type家族大比拼:



    Best Regards

    Yong Lu

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 Troy_Zhang 2019年4月27日 9:08
    2019年4月25日 6:47
    版主