第三次发了,反射如何获取子类属性的值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第三次发了,反射如何获取子类属性的值相关的知识,希望对你有一定的参考价值。

//类
class A
public int memberIdget;set;

class B
public string nameget;set;
public A aget;set
;
//赋值
B b = new B();
b.name = '123';
b.a.member = 1;如何用对象b通过反射获取到name的值我会,但是用同样的方法获取memberId的值就为null了。
用反射回去属性值:(b.GetType()).GetProperty("name").GetValue(b, null)//这个可以获取到name的值,但是(b.GetType()).GetProperty("memberId").GetValue(b, null)//这个获取memberId的值就为null了。。。
ps:不需要分析为什么我的方法获取不到memberId,只需要告诉我如何获取到memberId的值就好了

参考技术A (b.a.GetType()).GetProperty("memberId").GetValue(b.a,null) 参考技术B 为什么非要在B类中定义A对象呢?为什么不采用继承呢?这样全都可以获取值追问

A、B类可能会有属性名称一样,这样能区分么?

追答

如果采用继承,A类中的属性(排除私有属性,私有属性不会继承到子类)会继承到B类,直接在B类中就有A类的属性了,怎么会还重新定义一个呢?

追问

额,应该这么问。C#不支持多继承吧?如果再有一个C类,就不可以了。就算可以,B、C类可能会有名称一样的属性

追答

知道为什么在B类中不能获取A类的值吗?因为你根本没有在B类中实例化new一个A类,A类根本没有生存空间,所以就获取不到了哦,呵呵。只要在用的时候B b=new B();b.name="";b.A=new A();
A.menberID=1;,就可以得到A类的属性值了
解决了没有?解决了就给分卅

追问

A类是有值得,调试能通过B类找到A类某个属性的值,就是不知道怎么用代码获取出来。

本回答被提问者采纳

如何通过反射获取字符串属性的值?

【中文标题】如何通过反射获取字符串属性的值?【英文标题】:How can I get the value of a string property via Reflection? 【发布时间】:2010-11-02 13:05:16 【问题描述】:
public class Foo

   public string Bar get; set;

如何通过反射获取字符串属性 Bar 的值?如果 PropertyInfo 类型是 System.String,则以下代码将引发异常

Foo f = new Foo();
f.Bar = "Jon Skeet is god.";

foreach(var property in f.GetType().GetProperties())

 object o = property.GetValue(f,null); //throws exception TargetParameterCountException for String type

看来我的问题是该属性是索引器类型,带有 System.String。

另外,如何判断属性是否为索引器?

【问题讨论】:

在这里工作正常......还有其他事情发生吗? 您似乎没有发布足够的上下文代码? 是的。调试器说底层类型是字符串,但我怀疑还有其他事情发生。 Get property value from string using reflection in C# 的可能重复项 【参考方案1】:

您可以通过名称获取属性:

Foo f = new Foo();
f.Bar = "Jon Skeet is god.";

var barProperty = f.GetType().GetProperty("Bar");
string s = barProperty.GetValue(f,null) as string;

关于后续问题: 索引器将始终命名为 Item 并在 getter 上有参数。 所以

Foo f = new Foo();
f.Bar = "Jon Skeet is god.";

var barProperty = f.GetType().GetProperty("Item");
if (barProperty.GetGetMethod().GetParameters().Length>0)

    object value = barProperty.GetValue(f,new []1/* indexer value(s)*/);

【讨论】:

那不准确。 Item 是索引器的默认名称,但任何人都可以使用索引器属性上的 IndererNameAttribute 来更改它。您必须在类型上查找 DefaultMemberAttribute 才能获得实际的索引器名称。 我完全不知道 IndexerName 属性!谢谢你。您可以在此处找到更多信息:bartdesmet.net/blogs/bart/archive/2006/09/09/4408.aspx 谢谢 Jb Evain。 如果我只有一个具有完整类名的字符串,以及像 MyNameSpace1.X.Y.Z.ClassName 和 PropertyName 这样的属性名称?【参考方案2】:

我无法重现该问题。您确定您没有尝试在某些具有索引器属性的对象上执行此操作吗?在这种情况下,您在处理 Item 属性时会抛出您遇到的错误。 另外,您可以这样做:


public static T GetPropertyValue<T>(object o, string propertyName)

      return (T)o.GetType().GetProperty(propertyName).GetValue(o, null);


...somewhere else in your code...
GetPropertyValue<string>(f, "Bar");

【讨论】:

【参考方案3】:
Foo f = new Foo();
f.Bar = "x";

string value = (string)f.GetType().GetProperty("Bar").GetValue(f, null);

【讨论】:

【参考方案4】:
var val = f.GetType().GetProperty("Bar").GetValue(f, null);

【讨论】:

【参考方案5】:
Foo f = new Foo();
f.Bar = "Jon Skeet is god.";

foreach(var property in f.GetType().GetProperties())

    if(property.Name != "Bar")
    
         continue;
    
    object o = property.GetValue(f,null); //throws exception TargetParameterCountException for String type

这是后续行动:

class Test

    public class Foo
    
        Dictionary<string, int> data =new Dictionary<string,int>();
        public int this[string index]
        
            get  return data[index]; 
            set  data[index] = value; 
        

        public Foo()
        
            data["a"] = 1;
            data["b"] = 2;
        
    

    public Test()
    
        var foo = new Foo();
        var property = foo.GetType().GetProperty("Item");
        var value = (int)property.GetValue(foo, new object[]  "a" );
        int i = 0;
    

【讨论】:

基于其他 cmets,您需要将 get 值的 null 更改为正确的索引器值。【参考方案6】:
PropertyInfo propInfo = f.GetType().GetProperty("Bar");
object[] obRetVal = new Object[0];
string bar = propInfo.GetValue(f,obRetVal) as string;

【讨论】:

反对票到底是为了什么?此代码按预期工作。【参考方案7】:

任意对象的属性值很容易通过如下扩展方法获取:

public static class Helper
    
        public static object GetPropertyValue(this object T, string PropName)
        
            return T.GetType().GetProperty(PropName) == null ? null : T.GetType().GetProperty(PropName).GetValue(T, null);
        
    

用法是:

Foo f = new Foo();
f.Bar = "x";
var balbal = f.GetPropertyValue("Bar");

【讨论】:

感谢猫王,这可以修改为:return T.GetType().GetProperty(PropName)?.GetValue(T, null);。 blogs.msdn.microsoft.com/jerrynixon/2014/02/26/…【参考方案8】:

带有 object 和 null 的 getvalue 对我来说非常有用。感谢您的帖子。

上下文:循环遍历新员工的 MVC 模型中的所有属性并确定它们的表单发布值:

newHire => 模型,具有许多属性,我想将其发布的表单值单独写入一组数据库记录

foreach(var propertyValue in newHire.GetProperties())

string propName = propertyValue.Name;

string postedValue = newHire.GetType().GetProperty(propName).GetValue(newHire, null).ToString();


【讨论】:

这个简单的答案救了我的命。谢谢!【参考方案9】:

要通过仅传递对象来获取对象的属性名称,您可以使用此函数可能会起作用。

只需将 object 对象变成一个类并传递给它。

 public void getObjectNamesAndValue(object obj)
    
        Type type = obj.GetType();
        BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
        PropertyInfo[] prop = type.GetProperties(flags);
        foreach (var pro in prop)
        
            System.Windows.Forms.MessageBox.Show("Name :" + pro.Name + " Value : "+  pro.GetValue(obj, null).ToString());
        

    

但这仅在对象属性为“公共”时才有效

【讨论】:

以上是关于第三次发了,反射如何获取子类属性的值的主要内容,如果未能解决你的问题,请参考以下文章

如何反射取得一个对象中所有字段的值

c# 如何通过反射 获取属性值

java中如何通过反射获取类的属性

java对象值的copy

C#中基类属性值在子类中设置,如何在基类的方法中获取子类设置的值?

如何更改通过反射 C# 获取的属性值