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

时间:2021-05-21 15:07:07
public class Foo
{
   public string Bar {get; set;}
}

How do I get the value of Bar, a string property, via reflection? The following code will throw an exception if the PropertyInfo type is a System.String

如何通过反射获得字符串属性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
}

It seems that my problem is that the property is an indexer type, with a System.String.

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

Also, how do I tell if the property is an indexer?

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

8 个解决方案

#1


You can just get the property by name:

您可以按名称获取酒店:

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

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

Regarding the follow up question: Indexers will always be named Item and have arguments on the getter. So

关于后续问题:索引器将始终命名为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)*/});
}

#2


I couldn't reproduce the issue. Are you sure you're not trying to do this on some object with indexer properties? In that case the error you're experiencing would be thrown while processing the Item property. Also, you could do this:

我无法重现这个问题。你确定你没有尝试在具有索引器属性的某个对象上执行此操作吗?在这种情况下,处理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
}

And here is for the followup:

这是为了后续:

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

#6


PropertyInfo propInfo = f.GetType().GetProperty("Bar");
object[] obRetVal = new Object[0];
string bar = propInfo.GetValue(f,obRetVal) as string;

#7


Its easy to get property value of any object by use Extension method like:

通过使用Extension方法很容易获得任何对象的属性值,如:

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

Usage is:

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

#8


the getvalue with object and null worked great for me. Thanks for the posts.

带有object和null的getvalue对我来说很有用。谢谢你的帖子。

Context: Looping through all properties in an MVC model for New Hires and determining their form posted values:

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

newHire => the Model, with many properties, whose posted form values I want to write individually to a set of database records

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

foreach(var propertyValue in newHire.GetProperties())
{
string propName = propertyValue.Name;

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

}

#1


You can just get the property by name:

您可以按名称获取酒店:

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

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

Regarding the follow up question: Indexers will always be named Item and have arguments on the getter. So

关于后续问题:索引器将始终命名为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)*/});
}

#2


I couldn't reproduce the issue. Are you sure you're not trying to do this on some object with indexer properties? In that case the error you're experiencing would be thrown while processing the Item property. Also, you could do this:

我无法重现这个问题。你确定你没有尝试在具有索引器属性的某个对象上执行此操作吗?在这种情况下,处理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
}

And here is for the followup:

这是为了后续:

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

#6


PropertyInfo propInfo = f.GetType().GetProperty("Bar");
object[] obRetVal = new Object[0];
string bar = propInfo.GetValue(f,obRetVal) as string;

#7


Its easy to get property value of any object by use Extension method like:

通过使用Extension方法很容易获得任何对象的属性值,如:

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

Usage is:

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

#8


the getvalue with object and null worked great for me. Thanks for the posts.

带有object和null的getvalue对我来说很有用。谢谢你的帖子。

Context: Looping through all properties in an MVC model for New Hires and determining their form posted values:

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

newHire => the Model, with many properties, whose posted form values I want to write individually to a set of database records

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

foreach(var propertyValue in newHire.GetProperties())
{
string propName = propertyValue.Name;

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

}