使用 'path' 使用 system.Reflection 访问基础 class 成员
Accessing base class member with system.Reflection using 'path'
所以我有这样的东西:
using System.Reflection;
public class SomeFieldsGrouped{
public int foo;
public string bar;
//<etc>
}
public class A{
public SomeFieldsGrouped someFieldsGroupedInA;
//<etc>
}
public class B : A{
public int ffo;
//<etc>
}
public class YetAnotherClass
{
public B b; //Instantiated and stuff
public string bbr = "someFieldsGroupedInA.foo";
public static object GetPropertyValue (object o, string path)
{
object value = o;
string[] pathComponents = path.Split (new char[]{'.'}, StringSplitOptions.RemoveEmptyEntries);
if (pathComponents.Length == 1) {
return value.GetType ().GetField (pathComponents [0]).GetValue (o);
}
foreach (var component in pathComponents) {
value = value.GetType ().GetProperty (component).GetValue (value, null);//this is where it stops everytime
}
return value;
}
public void Main(){
object o = GetPropertyValue(b, bbr); //where is your god now?
}
}
(请记住它不是实际代码)
我想要完成的是创建一个基于反射的方法,通过它我可以访问任何 属性 路径作为字符串。现在这里发生了一件有趣的事情,我应该能够访问 "someFieldsGroupedInA",因为它是基础 class 成员。我可以用 b.SomeFieldsGroupedInA 做到这一点,但为什么我不能用 Reflection?
如果有人能告诉我大体方向,我在哪里可以找到类似我要写的东西,因为对我来说,制作适用于数组和其他东西的东西会非常困难,我会真的很感谢
您的代码的一个问题是您在 类 中定义字段,但是当您尝试访问它们时,您使用 GetProperty
而不是 GetField
。
要修复它,请替换此代码(在循环中):
value = value.GetType().GetProperty (component).GetValue (value, null);
使用此代码:
value = value.GetType().GetField(component).GetValue(value);
如果 path
可以指定属性 and/or 字段,那么您应该检查代码以查看是否存在具有特定名称的 属性。如果没有找到,它会检查是否存在具有该名称的字段。
更好的是,正如@Silvermind 所说,最好使用属性而不是字段。这是您的 类 的样子:
public class SomeFieldsGrouped{
public int foo {get;set;}
public string bar {get;set;}
//<etc>
}
public class A{
public SomeFieldsGrouped someFieldsGroupedInA {get;set;}
//<etc>
}
public class B : A{
public int ffo {get;set;}
//<etc>
}
您的方法将如下所示:
public static object GetPropertyValue (object o, string path)
{
object value = o;
string[] pathComponents = path.Split (new char[]{'.'}, StringSplitOptions.RemoveEmptyEntries);
if (pathComponents.Length == 1) {
return value.GetType().GetProperty(pathComponents [0]).GetValue (o, null);
}
foreach (var component in pathComponents) {
value = value.GetType().GetProperty (component).GetValue (value, null);
}
return value;
}
所以我有这样的东西:
using System.Reflection;
public class SomeFieldsGrouped{
public int foo;
public string bar;
//<etc>
}
public class A{
public SomeFieldsGrouped someFieldsGroupedInA;
//<etc>
}
public class B : A{
public int ffo;
//<etc>
}
public class YetAnotherClass
{
public B b; //Instantiated and stuff
public string bbr = "someFieldsGroupedInA.foo";
public static object GetPropertyValue (object o, string path)
{
object value = o;
string[] pathComponents = path.Split (new char[]{'.'}, StringSplitOptions.RemoveEmptyEntries);
if (pathComponents.Length == 1) {
return value.GetType ().GetField (pathComponents [0]).GetValue (o);
}
foreach (var component in pathComponents) {
value = value.GetType ().GetProperty (component).GetValue (value, null);//this is where it stops everytime
}
return value;
}
public void Main(){
object o = GetPropertyValue(b, bbr); //where is your god now?
}
}
(请记住它不是实际代码)
我想要完成的是创建一个基于反射的方法,通过它我可以访问任何 属性 路径作为字符串。现在这里发生了一件有趣的事情,我应该能够访问 "someFieldsGroupedInA",因为它是基础 class 成员。我可以用 b.SomeFieldsGroupedInA 做到这一点,但为什么我不能用 Reflection?
如果有人能告诉我大体方向,我在哪里可以找到类似我要写的东西,因为对我来说,制作适用于数组和其他东西的东西会非常困难,我会真的很感谢
您的代码的一个问题是您在 类 中定义字段,但是当您尝试访问它们时,您使用 GetProperty
而不是 GetField
。
要修复它,请替换此代码(在循环中):
value = value.GetType().GetProperty (component).GetValue (value, null);
使用此代码:
value = value.GetType().GetField(component).GetValue(value);
如果 path
可以指定属性 and/or 字段,那么您应该检查代码以查看是否存在具有特定名称的 属性。如果没有找到,它会检查是否存在具有该名称的字段。
更好的是,正如@Silvermind 所说,最好使用属性而不是字段。这是您的 类 的样子:
public class SomeFieldsGrouped{
public int foo {get;set;}
public string bar {get;set;}
//<etc>
}
public class A{
public SomeFieldsGrouped someFieldsGroupedInA {get;set;}
//<etc>
}
public class B : A{
public int ffo {get;set;}
//<etc>
}
您的方法将如下所示:
public static object GetPropertyValue (object o, string path)
{
object value = o;
string[] pathComponents = path.Split (new char[]{'.'}, StringSplitOptions.RemoveEmptyEntries);
if (pathComponents.Length == 1) {
return value.GetType().GetProperty(pathComponents [0]).GetValue (o, null);
}
foreach (var component in pathComponents) {
value = value.GetType().GetProperty (component).GetValue (value, null);
}
return value;
}