- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
假设我有下面的类:
public class Car
{
public Car()
{
}
}
public class Motor
{
public Motor()
{
}
}
public class Vehicle
{
public Vehicle()
{
SuperCar = new Car();
}
public Car SuperCar { get; set; }
public string TestName { get; set; }
}
让我们看看下面的代码:
Vehicle vehicle = new Vehicle();
Car superCar = vehicle.SuperCar;
现在,如果我们只给出 Car 实例,它是 superCar,是否可以从反射中知道 superCar 实例实际上属于 Vehicle 的属性之一?
好的。感谢您的意见。我认为通过反射是可能的。
因此,如果我们扩展代码:
PropertyInfo[] props = vehicle.GetType().GetProperties();
前提是,我们只给出:
PropertyInfo propInfo = props[0];
我们可以通过MemberInfo知道这个propInfo到底属于哪个类:
Console.WriteLine(((System.Reflection.MemberInfo)(propInfo)).DeclaringType.Name);
It would return Vehicle.
谢谢!
最佳答案
简答
不,这是不可能的。反射是一种读取程序集和其中类型的静态元数据 的方法。有关类型属性的信息是此类元数据的示例。但是诸如“哪些对象正在引用某个对象”之类的信息不是静态元数据。它是一个运行时数据,通常无法在 .NET 中访问。另一件事是,它真的没有必要。总是有更好的方法来设计东西(比如指向其 parent 的引用)。换句话说,您真的永远都不需要这样做,所以最好记住这是不可能的。
长答案
综上所述,我想指出的是,在惊人的 Microsoft.Diagnostics.Runtime 的帮助下,你想做什么是可能的图书馆。正如作者所说:
ClrMD is a set of advanced APIs for programmatically inspecting a crash dump of a .NET program much in the same way as the SOS Debugging Extensions (SOS). It allows you to write automated crash analysis for your applications and automate many common debugger tasks.
其实平时工作的时候也可以附加到自己的进程,分析一下。下面的代码非常 hacky,可能永远不应该使用,但它有效并展示了 .NET 世界的强大之处:
public bool IsReferencedByAnyVehicle(Car car)
{
ulong ptr;
// Nasty way of getting address
unsafe
{
TypedReference tr = __makeref(car);
ptr = (ulong)(**(IntPtr**)(&tr));
Console.WriteLine(ptr);
}
// Attach to the process itself, hence only AttachFlag.Passive flag is possible
var process = Process.GetCurrentProcess();
using (var dataTarget = DataTarget.AttachToProcess(process.Id, 250, AttachFlag.Passive))
{
string dacLocation = dataTarget.ClrVersions[0].TryGetDacLocation();
ClrRuntime runtime = dataTarget.CreateRuntime(dacLocation);
ClrHeap heap = runtime.GetHeap();
// Get all Vehicle objects from heap that has reference to ptr
var refs = heap.EnumerateObjects()
.Select(obj => new
{
Type = heap.GetObjectType(obj),
ObjectAddress = obj
})
.Where(t => t.Type != null &&
t.Type.Name.EndsWith("Vehicle") &&
GetReferences(t.Type, t.ObjectAddress).Contains(ptr))
.Any();
// Cleanup
runtime.Flush();
return refs;
}
}
public List<ulong> GetReferences(ClrType type, ulong objRef)
{
var result = new List<ulong>();
type.EnumerateRefsOfObjectCarefully(objRef, (addr, _) => result.Add(addr));
return result;
}
然后进行简单测试:
Vehicle vehicle = new Vehicle();
Car superCar = vehicle.SuperCar;
Car localCar = new Car();
bool isSuperCar = IsReferencedByAnyVehicle(superCar); // true
bool isLocalCar = IsReferencedByAnyVehicle(localCar); // false
注意:对于附加到自身,只有 AttachFlag.Passive 是可能的,描述为:
Performs a "passive" attach, meaning no debugger is actually attached to the target process. The process is not paused, so queries for quickly changing data (such as the contents of the GC heap or callstacks) will be highly inconsistent** unless the user pauses the process through other means.
因此结果可能并不总是确定性的。
关于c# - .NET 反射来识别属性关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21314697/
你能比较一下属性吗 我想禁用文本框“txtName”。有两种方式 使用javascript,txtName.disabled = true 使用 ASP.NET, 哪种方法更好,为什么? 最佳答案 我
Count 属性 返回一个集合或 Dictionary 对象包含的项目数。只读。 object.Count object 可以是“应用于”列表中列出的任何集合或对
CompareMode 属性 设置并返回在 Dictionary 对象中比较字符串关键字的比较模式。 object.CompareMode[ = compare] 参数
Column 属性 只读属性,返回 TextStream 文件中当前字符位置的列号。 object.Column object 通常是 TextStream 对象的名称。
AvailableSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。 object.AvailableSpace object 应为 Drive 
Attributes 属性 设置或返回文件或文件夹的属性。可读写或只读(与属性有关)。 object.Attributes [= newattributes] 参数 object
AtEndOfStream 属性 如果文件指针位于 TextStream 文件末,则返回 True;否则如果不为只读则返回 False。 object.A
AtEndOfLine 属性 TextStream 文件中,如果文件指针指向行末标记,就返回 True;否则如果不是只读则返回 False。 object.AtEn
RootFolder 属性 返回一个 Folder 对象,表示指定驱动器的根文件夹。只读。 object.RootFolder object 应为 Dr
Path 属性 返回指定文件、文件夹或驱动器的路径。 object.Path object 应为 File、Folder 或 Drive 对象的名称。 说明 对于驱动器,路径不包含根目录。
ParentFolder 属性 返回指定文件或文件夹的父文件夹。只读。 object.ParentFolder object 应为 File 或 Folder 对象的名称。 说明 以下代码
Name 属性 设置或返回指定的文件或文件夹的名称。可读写。 object.Name [= newname] 参数 object 必选项。应为 File 或&
Line 属性 只读属性,返回 TextStream 文件中的当前行号。 object.Line object 通常是 TextStream 对象的名称。 说明 文件刚
Key 属性 在 Dictionary 对象中设置 key。 object.Key(key) = newkey 参数 object 必选项。通常是 Dictionary 
Item 属性 设置或返回 Dictionary 对象中指定的 key 对应的 item,或返回集合中基于指定的 key 的&
IsRootFolder 属性 如果指定的文件夹是根文件夹,返回 True;否则返回 False。 object.IsRootFolder object 应为&n
IsReady 属性 如果指定的驱动器就绪,返回 True;否则返回 False。 object.IsReady object 应为 Drive&nbs
FreeSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。只读。 object.FreeSpace object 应为 Drive 对象的名称。
FileSystem 属性 返回指定的驱动器使用的文件系统的类型。 object.FileSystem object 应为 Drive 对象的名称。 说明 可
Files 属性 返回由指定文件夹中所有 File 对象(包括隐藏文件和系统文件)组成的 Files 集合。 object.Files object&n
我是一名优秀的程序员,十分优秀!