class a
{
public  string name;
}public getProName(string proValue)
{
    .......
}如何实现 getProName(a.name) == "name"    ?用文字描述的话,就是在某个方法里,当它被调用的时候,假如参数是某个对象的属性,那么在方法里 如何获取该变量在它的类里的成员名称?能实现否?

解决方案 »

  1.   

    public void PrintProperties<T>(T t)
            {
                if (t == null)
                {
                    return;
                }            PropertyInfo[] properties = t.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
                if (properties.Length <= 0)
                {
                    return;
                }            foreach (PropertyInfo item in properties)
                {
                    string name = item.Name;
                    object value = item.GetValue(t, null);
                    if (item.PropertyType.IsValueType || item.PropertyType.Name.StartsWith("String"))
                    {
                        Console.WriteLine("{0}:{1}", name,value);
                    }
                    else
                    {
                        foreach (PropertyInfo itemsub in value.GetType().GetProperties())
                        {                        PrintProperties(value);
                        }
                    }
                }
            }
      

  2.   

    有从"name"找到值的.你却要从变量名到string.
      

  3.   

    是在一个类中还是两个类中?
    如果在一个类中,直接可以拿来作用
    如果在两个类中,这两个类必须有继承关系,也可以直接拿来用
    没有继承关系的话,NEW一下就可以了~
      

  4.   

    使用反射。   
      相关信息请参照:   
      ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpcondynamicallyloadingusingtypes.htm
      

  5.   

    http://topic.csdn.net/t/20030902/11/2214138.html
      

  6.   

    public getProName(string proValue) 

        // 在这里的时候,“关于 proValue 是从那里来的”这一部分信息已经丢失,已经丢失的信息,你是不可能找回来的
      

  7.   

    如果你要需要你所需要的功能,只能是设计这样的函数:public string getProName(PropertyInfo pro) 

      

  8.   

    这个问题很变态,首先,当你把一个对象的属性当作参数传入的时候,实际的参数已经转换成属性值了,比如说你的例子中的a.name,调用方式为 getProName(a.name),对于 getProName 方法来说,a.name 只不过是一个 string,你甚至都不知道这个参数是通过 a 对象的属性得来的,怎么反射?
    我想除非你自己做一个源码分析器,才有可能得出吧。
      

  9.   

    这个问题其实来自我一个很普通的需求,数据库有个表 User,字段若干 id,name,sex...
    程序里建立个映射类 User,有对应的若干属性id,name,sex...现在有个获取用户集合的方法,想指定返回的字段(也就是user对象要填充的属性)。List<User> GetUserList(string fields)
    {
       // 返回的用户里的属性里只有包含在参数fields 才有值。
    }执行GetUserList("id,name")  于是返回的user中id和name有值,sex是空的。
    当然,执行GetUserList("id")  返回的user只有id,无其他属性值。
    很明显,调用方法GetUserList 传的参数列表,只能用硬编码方式,就是直接写字段名进字符串。如果存在我想要的那个方法,比如叫 ExpToString(exp) (把某个表达式转换为字符串)
    能够实现  ExpToString(user.id)=="user.id";
    那么,前面那个方法调用的代码就可以改为GetUserList(ExpToString(user.id));这样写有什么好处呢?首先,编写代码的时候我们不容易写错,其次,一旦字段名更改了,vs能自动把所有代码中使用该字段
    的地方都自动修改过来,即使你不使用该功能,当你build项目的时候 系统也能给你报错,而如果你
    用的GetUserList("id")这种方式,那就只有到运行时候出错才能看到了。
      

  10.   

    反射就可以了,给你个微软写的例子://版权所有 (C) Microsoft Corporation。保留所有权利。// AttributesTutorial.cs
    // 本示例表明类属性和方法属性的用法。using System;
    using System.Reflection;
    using System.Collections;// IsTested 类是用户定义的自定义属性类。
    // 它可以应用于任何声明,包括
    //  - 类型(结构、类、枚举、委托)
    //  - 成员(方法、字段、事、属性、索引器)
    // 使用它时不带参数。
    public class IsTestedAttribute : Attribute
    {
        public override string ToString()
        {
            return "Is Tested";
        }
    }// AuthorAttribute 类是用户定义的属性类。
    // 它只能应用于类和结构声明。
    // 它采用一个未命名的字符串参数(作者的姓名)。
    // 它有一个可选的命名参数 Version,其类型为 int。
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
    public class AuthorAttribute : Attribute
    {
        // 此构造函数为属性类指定未命名的参数。
        public AuthorAttribute(string name)
        {
            this.name = name;
            this.version = 0;
        }    // 此属性为只读(它没有 set 访问器)
        // 因此,不能将其用作此属性的命名参数。
        public string Name 
        {
            get 
            {
                return name;
            }
        }    // 此属性可读写(它有 set 访问器)
        // 因此,将此类用作属性类时,
        // 可以将其用作命名参数。
        public int Version
        {
            get 
            {
                return version;
            }
            set 
            {
                version = value;
            }
        }    public override string ToString()
        {
            string value = "Author : " + Name;
            if (version != 0)
            {
                value += " Version : " + Version.ToString();
            }
            return value;
        }    private string name;
        private int version;
    }// 此处,将用户定义的自定义属性 AuthorAttribute 附加
    // 到 Account 类。创建属性时,会将未命名的
    // 字符串参数传递到 AuthorAttribute 类的构造函数。
    [Author("Joe Programmer")]
    class Account
    {
        // 将自定义属性 IsTestedAttribute 附加到此方法。
        [IsTested]
        public void AddOrder(Order orderToAdd)
        {
            orders.Add(orderToAdd);
        }    private ArrayList orders = new ArrayList();
    }// 将自定义属性 AuthorAttribute 和 IsTestedAttribute 附加
    // 到此类。
    // 请注意 AuthorAttribute 的命名参数“Version”的用法。
    [Author("Jane Programmer", Version = 2), IsTested()]
    class Order
    {
        // 在此处添加资料...
    }class MainClass
    {
       private static bool IsMemberTested(MemberInfo member)
       {
            foreach (object attribute in member.GetCustomAttributes(true))
            {
                if (attribute is IsTestedAttribute)
                {
                   return true;
                }
            }
          return false;
       }    private static void DumpAttributes(MemberInfo member)
        {
            Console.WriteLine("Attributes for : " + member.Name);
            foreach (object attribute in member.GetCustomAttributes(true))
            {
                Console.WriteLine(attribute);
            }
        }    public static void Main()
        {
            // 显示 Account 类的属性
            DumpAttributes(typeof(Account));        // 显示已测试成员的列表
            foreach (MethodInfo method in (typeof(Account)).GetMethods())
            {
                if (IsMemberTested(method))
                {
                   Console.WriteLine("Member {0} is tested!", method.Name);
                }
                else
                {
                   Console.WriteLine("Member {0} is NOT tested!", method.Name);
                }
            }
            Console.WriteLine();        // 显示 Order 类的属性
            DumpAttributes(typeof(Order));        // 显示 Order 类的方法的属性
            foreach (MethodInfo method in (typeof(Order)).GetMethods())
            {
               if (IsMemberTested(method))
               {
                   Console.WriteLine("Member {0} is tested!", method.Name);
               }
               else
               {
                   Console.WriteLine("Member {0} is NOT tested!", method.Name);
               }
            }
            Console.WriteLine();
        }
    }
      

  11.   

    14 楼说的很对, 在现在c#的语法里,当使用参数a.name的时候,它仅仅是个普通的字符串变量,不包含它所在的对象的信息。
    所以,现在似乎不可能实现我的想法。
    但有时候确实觉得微软也有很笨的时候,当我敲入 user.name的时候,眼睁睁的看着它,却只能得到它的值,毫无办法得到"user.name"这个字符串。
      

  12.   

    在给你个winform的例子,这个更容易理解:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Reflection;namespace WindowsApplication3
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {
                Type t = typeof(Form1);
                MethodInfo[] info = t.GetMethods();
                foreach (MethodInfo i in info)
                {
                    MessageBox.Show(i.Name);
                }        }    }
    }
      

  13.   

    楼主的意思,是不是下面这个意思?
    如果表结构变更,对应的实体类的字段也变更的,原来字段叫name,现在改成myName了那代码里,使用user.name的地方都要跟着变成myName,否则就会编译错误了楼主是不是希望,实现字段名变更时,使用user.name的地方不用跟着改变呢?
      

  14.   

    这个问题确实够变态的。同意14楼不过不是不能实现,虽然我不知道实现的原理,但是有实现的例子不知道你使用过Newtonsoft.Json.dll没。一个C#的的json序列化与反序列化组件如果你写一个
    public class jt
    {
      public int count=1;
      public string str="测试";
      publick jt(){
      }
    }然后调用序列化
    jt tp=new jt();
    JavaScriptConvert.SerializeObject(tp);
    就会得到这样一个字符串串
    {"count":"1","str":"测试"};这就是LZ的曙光,反编译下Newtonsoft.Json.dll,看它是怎么获得count以及str的
    :)反射是从字符获得对象哦
      

  15.   

    .net 中是存在楼主所说的从 class.classname中得到classname字符串的
    应该和序列化 反序列化,以及智能感知的一些类有关,我以前碰到过,不过不记得了
    实在不行,你就反编译Newtonsoft.Json.dll看它怎么实现的吧
      

  16.   

    楼上的,我觉得实现{"count":"1","str":"测试"}这个一点不难,
    把 类的所有成员找出来,遍历一遍,把name和value打印出来就行了,
    我现在的问题并非是读取不到属性名字,利用反射能轻易获取到所有属性名称,属性类型,属性值,现在的难题是 无法根据
    某个实例的属性的值反推出属性名称。
      

  17.   

    a.name
    ----------
    这个只是一个string type value没有这个域的相关数据,如果传递MemberInfo mi就完全可以了实现了
      

  18.   


            public class TestClass
            {
                private string name;
                public string Name
                {
                    get { return string.IsNullOrEmpty(name) ? "Name" : name; }
                    set { name = value; }
                }            private string id;            public string Id
                {
                    get { return string.IsNullOrEmpty(id) ? "Id" : id; }
                    set { id = value; }
                }
                public string GetProName(string proValue)
                {
                    Type t = this.GetType();
                    foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                    {
                        if (pi.Name == proValue)
                            return pi.Name;
                    }
                    return "";
                }
            }
            static void Main(string[] args)
            {
                TestClass tc = new TestClass();
                Console.WriteLine(tc.GetProName(tc.Name));
                Console.WriteLine(tc.GetProName(tc.Id));
            }
    /*
    输出:
    Name
    Id
    */
      

  19.   

    就是说你并不清楚User类有哪些属性,那你怎么会用User.id 呢?你不怕这个id不存在?ExpToString(user.id)=="user.id";?我觉得还是要自己维护的,辟如一些动态的表单等?或者集合?权当是说说而已,LZ
      

  20.   

    差点错倒,不过看明白你的意思了:
    GetUserList(ExpToString(user.id)); 
    ExpToString(user.id),这里,把user这个类里面多定义几个变量就可以了,如:
    public class user
    {
        public string idFieldName {get;set;} //这里新增进来一个字段的信息
        public string id {get;set;}//假设这里是你原来的定义,是为了取得值r 
    }GetUserList(user.idFieldName); //这样调用不就实现了你想要的吗?
    如果你想传进去任意个参数,将getuserList的定义改成这样就可以了
    public GetUserList(params string FieldName) 
      

  21.   

    这样的代码只说明了 name = value 这总对印性才可能得到,否则就
    byebye
      

  22.   

    楼上的,你的确实是一种解决办法,但是似乎代码就累赘一些,而且并不是从实质上解决这个问题。
    因为你毕竟还是需要预先定义  public string idFieldName {get {return "id"}}比如当数据库里的id字段改名为iid的时候,你还是需要手动把这里"id" 改为 "iid"