使用反射在C#中设置嵌套值

本文关键字:设置 嵌套 反射 | 更新日期: 2023-09-27 18:25:04

我有一个名为Article的类,它使用了另一个名称为ZoneStock的类。这个ZoneStock类有一个整数ID。

我想使用反射来修改它,但它不起作用。

我在Stack Overflow上找到了一些例子,但我没能成功。

public void Edit(int Id, string Key, string Value)
    {
        Article Article = Db.ArticleById(Id);
      if (Key.Contains("."))  // in this case, Key = ZoneStock.Id
        {
            string[] Keys = Key.Split('.');
            PropertyInfo Lvl1 = Article.GetType().GetProperty(Keys[0]); //Keys[0] = ZoneStock
            Type T = Lvl1.PropertyType;
            PropertyInfo Lvl2 = T.GetProperty(Keys[1]); //Keys[1] = Id

            // Before this point it works, after ....
            Lvl2.SetValue(Lvl1, Convert.ChangeType(Value, Lvl2.PropertyType), null);
            Db.Update(ref Article);
        }
        else
        {
            // .......
        }
        Db.Save();
    }

使用反射在C#中设置嵌套值

我找到了一个解决问题的方法,它是:

[HttpPost]
    [ValidateAntiForgeryToken]
    public string Edit(int Id, string Key, string Value)
    {
        Article Article = Db.ArticleById(Id);
        if (Key.Contains(".")) //Property is a custom class
        {
            string[] Keys = Key.Split('.');
            PropertyInfo prop = Article.GetType().GetProperty(Keys[0]);
            Type type = prop.PropertyType;
            object propInstance = Db.Object(type, Convert.ToInt32(Value)); // See the code of this method below
            prop.SetValue(Article, propInstance);
            Db.Update(ref Article);
        }
        else // Property is a simple type: string, int, double, dattime etc.
        {
            PropertyInfo prop = Article.GetType().GetProperty(Key);
            prop.SetValue(Article, Convert.ChangeType(Value, prop.PropertyType), null);
            Db.Update(ref Article);
        }
        Db.Save();
        return Value;
    }
 public static object Object(Type type, int Id)
    {
        object Obj = Ctx.Set(type).Find(Id); //Ctx is may entityFramework Context
        return Obj;
    }

由于您将参数中的值直接分配给类型(Lvl1),而不是类型的实例,因此您似乎收到了类似"对象与目标类型不匹配"的错误消息。下面的代码应该可以直接赋值。

var newValue = Convert.ChangeType(Value, Lvl2.PropertyType);
Lvl2.SetValue(Lvl1.GetValue(Article), newValue);

根据评论更新基于新要求

如果级别1属性可能为null,则下面的代码将实例化该属性类型的实例。

// Article.ZoneStack is null
if (Lvl1.GetValue(Article) == null)
    Lvl1.SetValue(Article, Activator.CreateInstance(Lvl1.PropertyType));
// Article.ZoneStack now has a new instance of ZoneStack assigned
var newValue = Convert.ChangeType(Value, Lvl2.PropertyType);
Lvl2.SetValue(Lvl1.GetValue(Article), newValue);
// Article.ZoneStack.Id == newValue
相关文章: