获得由反射(C#)全“路径” [关闭](get full 'path' by ref

2019-07-17 16:06发布

是否有可能通过反射来获取完整的“路径”?

例如想象我有下面的类/属性。

public class Member
{
    public string Name;
    public Address Address;
}

public class Address
{
    public string Line1;
    public string Line2;
    public string Line3;
}

想象一下,我有这个类命名的实例m 。 是否有可能得到完整的路径为“Member.Address.Line1”(如字符串),通过反射,只通过传递某种方式m.Address.Line1

Answer 1:

如果你愿意使用Expression<Func<T>>那么是的,它应该是简单的。

只是这样做:

 public string GetFullPath<T>(Expression<Func<T>> action) {
  return action.Body.ToString();
}

var fullPath = GetFullPath(() => m.Address.Line1);

这不给你你想要什么,但它会很接近,你可以删除你不想要的位。

我将在该对象多一点挖过来,看看是否有一个更清洁的方式来让你更接近你想要什么。



Answer 2:

没有。

问题是,当你通过m.Address.Line1情况下,所有的方法接收是Line的实例,它有没有办法找出哪些实例引用它。

你当然可以,使该方法接受类似MyMethod(m, "Address", "Line1")但是这可能会毁掉整个目的(很难知道,因为你没有说你为什么想要这个)

你可能有一些运气Expression<T>虽然。



Answer 3:

首先,我要确保我明白你的问题...如果你想获得的价值m.Address.Line1通过传递一个字符串,如“m.Address.Line1”一些功能,然后是你可以做到这一点。 如果你想开始与1号线和导航上树,看看对象引用它,那么这是一个非常困难的问题,我也没有办法。

如果是第一种情况,那么我这样做的一篇文章我在CodeProject上写了一个文本模板逐渐填满。 代码本身是有点复杂,所以我不会张贴在这里,但这里的链接:

http://www.codeproject.com/Articles/505428/A-lightweight-recursive-text-template-data-formatt

该代码基本上拆分您在每个传递字符串“” 和递归向下导航对象树以找到您正在寻找的价值。 它也有东西像一些支持IEnumerable ,但只在模板填充(也就是不能导航到列表中的一个特定的指数)。



Answer 4:

我假设“Address”就是那不存在的,正如前面你说的那个类有三个字符串属性的东西! 1号线,2号线,3号线

我已经添加了一个额外属性“名称”持有类的名称,具有控制名称,所以我们可以对Name属性的基础上标记对象的不太一样,

此外,如果你需要这样的输出u必须跟踪创建的对象的,对于我宁愿一个列表类型。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace ConsoleApplication4
{
    class Member
    {
        public string Line1 { get; set; }
        public string Line2 { get; set; }
        public string Line3 { get; set; }
        public string Name { get; set; }

    }

    static class Program
    {
        private static readonly List<object> MyRefObjHolder = new List<object>();

        private static void Main()
        {

            Member m = new Member {Line1 = "line1", Line2 = "line2", Line3 = "line3", Name = "m"};

            Member n = new Member {Line1 = "line1", Line2 = "line2", Line3 = "line3", Name = "n"};

            MyRefObjHolder.Add(m);
            MyRefObjHolder.Add(n);


            string tmp1 = GetCompleteNameWithProperty("m.Line1");
            string tmp2 = GetCompleteNameWithProperty("n.Line1");
            Console.WriteLine(tmp1); // prints : Member.Line1
            Console.WriteLine(tmp2); // prints : Member.Line2
            Console.Read();

        }

        public static string GetCompleteNameWithProperty(string objref)
        {

            string[] obj = objref.Split('.');

            if (obj.Length < 2)
            {
                return null;
            }

            string className = obj[obj.Length - 2];
            string propName = obj[obj.Length - 1];

            string typeName = null;
            foreach (object o in MyRefObjHolder)
            {
                Type type = o.GetType();
                object name = type.GetProperty("Name").GetValue(o, null);
                if (name != null && name is string && (string) name == className)
                {
                    typeName = type.Name;
                }

            }

            //linq based solution, replce the foreach loop with linq one :P
            //string typeName = (from o in myRefObjHolder select o.GetType() into type where type.GetProperty(propName) != null select type.Name).FirstOrDefault();


            return typeName != null ? string.Format("{0}.{1}", typeName, propName) : null;
        }
    }

}


文章来源: get full 'path' by reflection (C#) [closed]
标签: c# reflection