当前位置:编程学习 > C#/ASP.NET >>

C#反射读取索引属性报错

基本代码如下:
PropertyInfo[] members=type.GetProperties(BindingFlags.Public |BindingFlags.Instance);
StringBuilder objString = new StringBuilder();
foreach (PropertyInfo field in members)
{
if(field!=null && field.CanRead && field.CanWrite )
{


try
{
object value=null;
//以下是判断索引属性
value = field.GetValue(obj,new object[1]{0}); //这句会报错“对象类型无法转换为目标类型。 ”field是自定义对象
}
catch
{
}
}
} --------------------编程问答-------------------- 可以把对象序列化为二进制的数据串,作为xml的一个节点。比较省事。
如果要实现你上述的,个人觉得只能遍历对象,将属性名称和属性值写入xml了 --------------------编程问答-------------------- 属性或者字段取值不需要参数,除非是方法,那你就应该用
var method = type.GetMethod(方法名);
var value = method.Invoke(obj, new object[1]{0}); --------------------编程问答-------------------- 根据索引这个不太好,一般是根据名字
if(field.Name == "abc" && field.CanRead && field.CanWrite )
{
     value = field.GetValue(obj,new null); 
} --------------------编程问答-------------------- field.GetValue(obj,null) --------------------编程问答--------------------
引用 2 楼 dongxinxi 的回复:
属性或者字段取值不需要参数,除非是方法,那你就应该用
var method = type.GetMethod(方法名);
var value = method.Invoke(obj, new object[1]{0});
获取一般属性不出错,如果获取的是索引化的属性,则会出错。即:
public object[] Items
{
get;
set;
} --------------------编程问答-------------------- 你必须先判断该属性是否为索引化属性,否则就会报错,在使用索引化属性获取值之前,要调用GetIndexParameters()方法判断返回的索引参数个数,为0的时候,GetValue的第二个参数必须为0,否则将会报错,而即使大于0的时候,你还必须判断索引参数类型,如果不是int类型的,你那样的调用也会报错,最后还需要考虑索引参数个数,如果不是1个的时候,你那样写也还是会报错。 --------------------编程问答-------------------- 修正下:为0的时候,GetValue的第二个参数必须为null,否则将会报错 --------------------编程问答--------------------
引用 6 楼 qldsrx 的回复:
。。。如果不是int类型的,你那样的调用也会报错,最后还需要考虑索引参数个数,如果不是1个的时候,你那样写也还是会报错。
是读取的object,具体怎么写呢? --------------------编程问答-------------------- 对于public object[] Items这样的属性,索引参数是0个,它根本就不是索引化属性,只是普通的属性,返回一个数组而已,因此GetValue的第二个参数必须是null。
所谓索引化属性,定义的时候必须类似这样定义的才是:
    [IndexerNameAttribute("属性名字在这里给")]
    public string this[int key]    
    {
        get
        {
            string returnValue = null;
            if (_indexedInstanceProperty.TryGetValue(key, out returnValue))
            {
                return returnValue;
            }
            else
            {
                return null;
            }
        }
        set
        {
            if (value == null)
            {
                throw new ApplicationException("IndexedInstanceProperty value can be the empty string, but it cannot be Nothing.");
            }
            else
            {
                if (_indexedInstanceProperty.ContainsKey(key))
                {
                    _indexedInstanceProperty[key] = value;
                }
                else
                {
                    _indexedInstanceProperty.Add(key, value);
                }
            }
        }
    }

--------------------编程问答--------------------
引用 9 楼 qldsrx 的回复:
对于public object[] Items这样的属性,索引参数是0个,它根本就不是索引化属性,只是普通的属性,返回一个数组而已,因此GetValue的第二个参数必须是null。
。。。
第二个参数为null会报错的哦,另外索引参数个数为1。 --------------------编程问答-------------------- 你是对自己写的类进行反射,还是对已经存在的类进行反射?
对于系统类,即使知道有Items属性,也不见得知道其定义,也就是说,你给的定义不正确。而对于自定义类,如果继承某个已有的类,覆盖其已经存在的类属性,就可能出现2个Items属性,其中一个被错误定义为了非索引化属性。
虽然定义属性的时候不能重名,但是不代表不会反射出重名属性来。如果你得到索引参数个数为1,别忘记索引参数的类型就是ParameterInfo,访问其ParameterType就可以知道其参数类型了。
对于这样的一个属性:
public object this[string key]{get;set;}
对外公开的就是一个返回object的索引化属性,其属性名没有给,使用默认值Items,索引类型为string.
而索引化属性也可以这样定义:
public object this[string key,int index] { get; set; }
这就是有2个索引参数的情况,2个以上索引参数的情况依次类推,处理在get、set方法内部处理,和数组的索引无关。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,