C# - 快速观察中的“可读”内部属性​​但不使用反射?

Posted

技术标签:

【中文标题】C# - 快速观察中的“可读”内部属性​​但不使用反射?【英文标题】:C# - Internal Properties "readable" in quickwatch but not using reflection? 【发布时间】:2012-03-28 21:17:23 【问题描述】:

我看到“快速监视”窗口可以访问所有属性,无论库中类的访问限制(内部、受保护、私有)如何,即使在完全不同的应用程序、lib 和命名空间。而我没有找到使用“反射”访问这些的方法。我特别想“阅读”(注意 - 只是阅读)程序集的内部属性。如果通过“内部”工作方式的设计(无法在同一命名空间外访问)无法做到这一点,那么 VS.NET 中的“快速监视”窗口如何“读取”它?

这是我使用的示例代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestLib

    public class TestInteralProp
    
        internal string PropertyInternal
        
            get  return "Internal Property!";  
        

        protected string PropertyProtected
        
            get  return "Protected Property!"; 
        

        string PropertyPrivate
        
            get  return "Private Property!"; 
        

        public string PropertyPublic
        
            get  return "Public Property!";  
        

        protected internal string PropertyProtectedInternal
        
            get  return "Protected Internal Property!"; 
        
    

当我为 TestInernalProp 类创建对象时,我可以在 quickwatch 中看到所有 4 个属性 -

当我使用反射访问除公共属性 (PropertyPublic) 之外的任何这些时,我得到一个空引用异常。

//this works
propTestObj.GetType().InvokeMember("PropertyPublic", System.Reflection.BindingFlags.GetProperty, null, propTestObj, null);
//this fails (obviously)
propTestObj.GetType().InvokeMember("PropertyInternal", System.Reflection.BindingFlags.GetProperty, null, propTestObj, null);

//this works
propTestObj.GetType().GetProperty("PropertyPublic").GetValue(propTestObj, null);
//this fails again
propTestObj.GetType().GetProperty("PropertyInternal").GetValue(propTestObj, null)

我不清楚“快速观看”如何访问这些。

【问题讨论】:

Properties not visible at design time but only at runtime的可能重复 您是否要在不同的程序集中进行反映?我知道有一些涉及内部的奇怪规则。更多信息:MSDN Internal Quick Watch 是 VS 的一部分,它是 C++ 和 COM 应用程序。它可以直接访问托管进程的内部结构,即 MethodDesc 表。 @Tin,我实际上是在另一个程序集中反映它。它可以与下面的 Olivier 所说的 bindingflags 重置一起使用。从下面 BrokenGlas 的 cmets 中也可以看出,反射器之类的工具如何能够反射几乎任何组件的内部。 【参考方案1】:

使用这些标志

BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance

此操作不需要GetProperty 标志。您可能还想添加Static

注意:您可以将标志与| 结合使用,因为它们的整数值是2 的幂。见this SO answer。


注意(针对 Lalman 和 shanks 对 Reflection 安全问题的担忧)

总有办法编写糟糕或危险的代码。做与不做取决于你。反射不是常规的做事方式,而是用于特殊工具的编程,如 o/r-mappers 或分析工具。反射非常强大;但是,您应该明智地使用它。

【讨论】:

这很酷,成功了。谢谢奥利维尔!我可以看到所有属性,包括私有属性。只是好奇——这也意味着也应该有一种方法来限制这一点?否则永远不可能隐藏内部代码。 如果您有权进行反思,则无法限制这一点 - 例如在 Silverlight 中你不能进行反射,所以这是一个“全局”限制

以上是关于C# - 快速观察中的“可读”内部属性​​但不使用反射?的主要内容,如果未能解决你的问题,请参考以下文章

将观察 .value 转换为 .child 快速添加

使用C# yield关键字来提高性能和可读性

将属性本身传递给 C# 中的参数

快速获取类名的用户可读版本(在 objc NSStringFromClass 中很好)

快速获取类名的用户可读版本(在 objc NSStringFromClass 中很好)

swift当某个属性要被外部访问但不希望被外部修改(内部可改)