简体   繁体   English

通过system.Reflection使用'path'访问基类成员

[英]Accessing base class member with system.Reflection using 'path'

So I have something like this: 所以我有这样的事情:

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?
    }
}

(keep in mind its not actual code) (请记住,它不是实际的代码)

What I'm trying to accomplish is to make a method based off Reflection, with which I can access ANY property with path as a string. 我要完成的工作是基于反射创建一个方法,通过它我可以使用路径作为字符串访问ANY属性。 Now this is a fun thing that happens here, I should be able to access "someFieldsGroupedInA", as it's base class member. 现在这是一件有趣的事情,我应该能够访问“ someFieldsGroupedInA”,因为它是基类成员。 And I can do so with b.SomeFieldsGroupedInA, but why can't I with Reflection? 我可以使用b.SomeFieldsGroupedInA来做到这一点,但是为什么我不能使用反射呢?

And if anybody can show me general direction where can I find something like the thing I'm gonna write, as its gonna be extremely hard for me to make something that would work with arrays and other stuff, I'd be really thankful. 而且,如果有人可以向我展示总体方向,那么我在哪里可以找到我要写的东西,因为它对我而言很难做出可以与数组和其他东西一起使用的东西,我将非常感激。

One problem with your code is that you are defining fields in your classes, but when you try to access them you use GetProperty instead of GetField . 代码的一个问题是您正在类中定义字段,但是当您尝试访问它们时,可以使用GetProperty而不是GetField

To fix it, replace this code (in the loop): 要修复它,请替换此代码(在循环中):

value = value.GetType().GetProperty (component).GetValue (value, null);

With this code: 使用此代码:

value = value.GetType().GetField(component).GetValue(value);

If the path could specify properties and/or fields, then you should make your code check to see if there is a property with the specific name. 如果path可以指定属性和/或字段,则应检查代码以查看是否存在具有特定名称的属性。 If it does not find it, it checks to see if there is a field with such name. 如果找不到,它将检查是否存在具有该名称的字段。

Better yet, as @Silvermind said, it is better to use properties instead of fields. 更好的是,正如@Silvermind所说,最好使用属性而不是字段。 Here is how your classes would look like: 这是您的班级样子:

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>
}

And your method would look like this: 您的方法将如下所示:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM