【问题标题】:get value of a property by its path in asp.net通过 asp.net 中的路径获取属性的值
【发布时间】:2012-08-21 21:24:28
【问题描述】:

here 给出了一个解决方案,通过提供类的名称来获取类的属性值。现在我想知道如何在这种情况下做同样的事情:

我有一个班级 MyClass 。这个类有一个名为 fooFoo 类型的属性。 Foo 有一个名为 barBar 类型的属性。 bar 有一个名为 value 的字符串属性。

属性不是静态的。

我希望能够通过将字符串 "foo.bar.value" 作为 propertyName 来获取 foo.bar.value 的值。换句话说,我想通过属性路径来获取它的值。

有可能吗?

【问题讨论】:

  • 这令人困惑:“我希望能够通过传递 "Foo.Bar.Value" 来获取 (Foo.Bar.Value) 的值。”
  • @TimSchmelter:更新问题
  • 我能问一下你为什么想要这样的东西吗?这听起来很奇怪,而且容易出错。
  • @TimSchmelter ,该类来自客户端。所以函数不知道结构是什么。所以路径也必须给出。由于某种原因,我不能使用界面来强制结构
  • 如果未来班级发生变化怎么办?为什么不能添加对dll的引用?你想如何获取你无法访问的类的属性?

标签: c# asp.net reflection


【解决方案1】:

您可以使用递归方法来做到这一点。每次调用都会使用 path 中的第一个单词获取值,然后使用其余部分再次调用该方法。

public object GetPropertyValue(object o, string path)
{
    var propertyNames = path.Split('.');
    var value = o.GetType().GetProperty(propertyNames[0]).GetValue(o, null);

    if (propertyNames.Length == 1 || value == null)
        return value;
    else
    {
        return GetPropertyValue(value, path.Replace(propertyNames[0] + ".", ""));
    }
}

【讨论】:

  • 应该注意,这可能不适用于空的path 参数。此外,它依赖于从不假设 null 值的属性。
  • @Amiram Korach:谢谢,表演怎么样。这种方法是一个不错的选择吗?
  • 反射不是那么快,但是通常你会在这个过程中做其他事情,比如从数据库或从慢得多的服务中获取数据。您需要测量时间并查看。
  • 另一个注意事项 - 如果属性名称在路径中出现两次 E.G. MyObject.Child.Child 这两个属性都将被 path.Replace 递归时删除。 SubString 可能是一种更安全的方法。
【解决方案2】:

这假定属性被命名为类。即Foo 类型的属性也被命名为Foo。如果没有这个假设,这个问题就缺少一些关键信息。

您可以使用string.Split method 在点处分隔字符串foo.bar.value。然后,您将拥有一个数组,其中每个属性名称都有一个元素。

遍历该数组并使用PropertyInfo.GetValue 检索属性值。一个操作中返回的值是在接下来的迭代中传递给GetValue 的实例。

string props = "foo.bar.value";
object currentObject = // your MyClass instance

string[] propertyChain = props.Split('.');
foreach (string propertyName in propertyChain) {
    if (propertyName == "") {
        break;
    }

    PropertyInfo prop = currentObject.GetType().GetProperty(propertyName);
    currentObject = prop.GetValue(currentObject);
    if (currentObject == null) {
        // somehow handle the situation that one of the properties is null
    }
}

更新:我添加了一个保护措施,以确保即使 props 为空也能正常工作。在这种情况下,currentObject 将保持对原始 MyClass 实例的引用。

【讨论】:

  • @reza:我已经更新了使用小写属性名称的答案。
【解决方案3】:

假设 FOO 是静态的,您可以像这样从字符串中获取类:

C# Reflection: How to get class reference from string?

...然后使用您链接到的其余帖子从那里获取属性和值:

Get property Value by its stringy name

如果 FOO 不是静态的,您将需要对实例使用反射(这将否定将类名称作为字符串传递的要求,因为您可以使用 GetType( )) - 记住 Bar 在类中没有值,除非它是静态的。

【讨论】:

    【解决方案4】:

    当您在这里指向问题的答案时,您需要利用 Reglection 来实现相同的目标。

    借助反射,您可以读取属性的值。

    类似的,

    // dynamically load assembly from file Test.dll
    Assembly testAssembly = Assembly.LoadFile(@"c:\Test.dll");
    // get type of class Calculator from just loaded assembly
    Type calcType = testAssembly.GetType("Test.Calculator");
    // create instance of class Calculator
    object calcInstance = Activator.CreateInstance(calcType);
    // get info about property: public double Number
    PropertyInfo numberPropertyInfo = calcType.GetProperty("Number");
    // get value of property: public double Number
    double value = (double)numberPropertyInfo.GetValue(calcInstance, null);
    

    您需要将代码放在一个函数中,然后根据您的要求拆分字符串

    public object getvalue(string propname)
    {
      //above code with return type object 
    }
    String[] array = string.Split("foo.bar.value");
    //call above method to get value of property..
    

    阅读详情:http://www.csharp-examples.net/reflection-examples/

    【讨论】:

    • 这不是答案。 OP 已经知道如何读取属性的值。问题是关于如何获取嵌套在子对象中的属性的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多